回答

收藏

如何优化MySQL查询(分组和顺序)

技术问答 技术问答 173 人阅读 | 0 人回复 | 2023-09-13

大家好,我有一个需要优化的查询。它的工作原理,但它的狗,表现明智。: ^' l& l  R, a. G2 g
内容如下:; G) q1 c+ H' D2 Q8 w" |: S6 X
SELECT  *
" h4 i, ]! o$ K' ^) \' _FROM    (
( D5 @$ I" n& D" t* r        SELECT  *0 t. a) A( U; I8 r& `3 c
        FROM    views# H7 ^& b3 g% L- d% \" {
        WHERE   user_id = '1'8 R2 O! u  G# M+ Y8 [! H/ T
        ORDER BY
/ s) B6 O6 A9 C: v* `                page DESC- k  [4 u3 \$ y% L' \) x
        ) v
& D" V; @4 U4 ^  ?" X) h( oGROUP BY
) u8 Z$ ~  ~# p) i1 ?        v.session3 Y& Y2 `3 E- D; X
我正在跟踪查看不同页面的视图,并且我想知道每个会话的最高页面,以便了解在任何给定条件下他们的点击量(从头到尾查看所有页面)会议。8 q- b! o( ^# ?0 ?
基本上,我想做的是在GROUP之前对结果进行排序。以上是实现的,成本很高。
5 U. [2 _) D% n谁能用这个方法拍我的脑袋?谢谢你们!
. T1 q  e3 ?+ x; I6 f: G* Z. \( r更新:
+ n- @+ I4 b# h说明:
2 C# t4 Y: y  Z% V  G. M1 o"1" &quotRIMARY"   ""    "ALL"   \N  \N  \N  \N  "3545"  "Using temporary; Using filesort"
5 v7 p3 O1 W+ r"2" "DERIVED"   "views" "index" \N  "page"  "5" \N  "196168"    "Using where"0 ]6 N4 {/ S7 y6 h% z- x7 O8 M
模式:
* ]& t6 I, q6 l) IID       int(8) unsigned  (NULL)     NO      PRI     (NULL)   auto_increment  select,insert,update,references         
! Q; \' U# p1 C0 M( t. a% `page     int(8)           (NULL)     YES     MUL     (NULL)                   select,insert,update,references         , [( q2 L7 y* J3 n$ F+ h- }  ~( f
user_id  int(8)           (NULL)     YES             (NULL)                   select,insert,update,references         
" e# S3 ~# @. bsession  int(8)           (NULL)     YES             (NULL)                   select,insert,update,references         
3 G, |+ u0 ^- W, T: N: E+ icreated  datetime         (NULL)     NO                                       select,insert,update,references! s3 A9 i4 f- \& l; a
索引信息:
0 J. D1 [% i1 h2 z; `% tviews            0  PRIMARY              1  ID           A               196008    (NULL)  (NULL)          BTREE
9 @' o7 H! ?3 hviews            1  page                 1  page         A                  259    (NULL)  (NULL)  YES     BTREE! C3 y. Q: ]8 z4 p) t8 g* A
               
3 L, m8 }- g3 |! `5 O) T解决方案:8 l# P. ]" s' ~0 d( y; f" _
               
2 h* {/ ^, N' s$ ^1 G, d% F9 ^# n9 X- x+ w

4 n5 [  i. f+ X9 L% _' `- g               
0 v! q  W! R" v3 X* a. u我正在跟踪查看不同页面的视图,并且我想知道每个会话的最高页面,以便了解在任何给定条件下他们的点击量(从头到尾查看所有页面)会议。8 X% T6 j8 H! J, s+ t
* H% w9 x9 D8 h, j9 V. c* Q
分组之前先订购是一种非常不可靠的方法。
5 u. Z2 j+ x: ?0 [! d0 C( E$ y7 cMySQL扩展GROUP BY语法:您可以在SELECTandORDER BY子句中使用未分组和未聚合的字段。
: z- ?1 R" @" f' Y在这种情况下,page每个输出一个随机值session。
& J+ j* `% M& R文档
) h* s9 f, a8 I3 T5 o明确指出,您永远不应对将确切确定为哪个值做任何假设:
# ~: G" ?" h) P3 h/ b
% r6 m' U6 [* m; W" i7 J" n- U( ]如果您从GROUP
6 M. j0 g7 e/ a: _. f, ^BY零件中省略的列在组中不是恒定的,请不要使用此功能。服务器可以自由地从组中返回任何值,因此除非所有值都相同,否则结果是不确定的。
1 Z2 S' G4 L2 D$ i' \
1 z, h; r% i: t5 F但是,实际上,将返回扫描的第一行中的值。9 g  y* T  T* l
由于您ORDER BY page DESC在子查询中使用,因此该行恰好是page每个会话最多的行。) G6 m4 ]2 D, I8 I+ m0 l( Q
您不应该依赖它,因为此行为没有记录,并且如果在下一版本中将返回其他行,则不会将其视为错误。0 S. x, \9 N; ^0 R2 ^
但是,您甚至不必做这些令人讨厌的把戏。
( z, V2 L4 v5 Y5 ?, o; ^$ l% }只需使用聚合函数:) x6 S- p+ Q/ j& q/ x
SELECT  MAX(page)0 q4 I0 V4 f( \7 {$ P& q! p  N1 |8 v
FROM    views
6 F4 h& E4 B2 a0 X% Q/ XWHERE   user_id = '1'7 m  f+ X# l+ D& q$ `/ I$ L
GROUP BY6 J7 F1 |! \2 @
        session- e1 t6 ^9 }. V
这是记录在案的,干净的方法来做您想要的。$ ]! x6 J# w3 j- o  w7 H
创建一个复合索引(user_id, session, page)以使查询运行更快。/ u& W- B8 R$ F- \8 F
如果您需要表中的所有列,而不仅是聚合的列,请使用以下语法:; `% X0 K# E2 W4 v
SELECT  v.*5 e/ Y, m! d3 P( S1 g6 o2 p
FROM    (
7 ~2 j" R$ i) J9 A& Q9 z5 V        SELECT  DISTINCT user_id, session
5 J6 k: C7 h- Y2 [+ t& b        FROM    views. Z9 d! r- g, i: H4 c9 G) H4 ]
        ) vo
+ Z1 M7 U' ]& D5 U$ h, ]  BJOIN    views v2 y# b5 [# a4 R3 ]$ t4 C$ J
ON      v.id =
* u4 [) N0 X3 h6 a# z/ U  P        (* y/ m3 ?+ j7 U6 [
        SELECT  id- s6 F6 t* |7 u: |
        FROM    views vi" A8 G5 F6 c3 }4 l$ m# v. @
        WHERE   vi.user_id = vo.user_id& e- \; ?  |+ z" h$ H
                AND vi.session = vo.session
, r: u* i$ {# t& n  S4 H5 _6 z2 p( @        ORDER BY
7 L+ a4 Z# k/ ^: ]5 M, d                page DESC& n5 V8 L1 D* N# X
        LIMIT 1% P0 p( J1 V2 n
        )) v. x% p' |9 _# Z' h
这假设id是PRIMARY KEYon views。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则