回答

收藏

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

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

大家好,我有一个需要优化的查询。它的工作原理,但它的狗,表现明智。4 ?+ j2 j2 ]5 p: I8 w8 f0 C. L
内容如下:, F0 ]7 @8 k/ \7 q1 \. \  q6 [
SELECT  *
* j! L& \  |) @2 MFROM    (
1 G9 Y$ a% j) U        SELECT  *
2 D: \& u8 t0 l5 n  \        FROM    views% l' I& a" Y! l3 M" E
        WHERE   user_id = '1': J! ]  p4 W" f% t
        ORDER BY  J; V3 l0 w$ |+ G& D
                page DESC& R4 t! B/ L8 n2 C8 I+ X$ C
        ) v2 ]# E$ \! C* E7 n5 E/ w! U% Q4 D8 @
GROUP BY
! c' T9 d, [! V. }5 E4 J" W        v.session
7 ^2 U2 @' M* E+ i+ q! H我正在跟踪查看不同页面的视图,并且我想知道每个会话的最高页面,以便了解在任何给定条件下他们的点击量(从头到尾查看所有页面)会议。
. w. k* @& F  o7 N3 ~$ d基本上,我想做的是在GROUP之前对结果进行排序。以上是实现的,成本很高。
9 v  H5 p; i  {  I3 S7 y* G; T谁能用这个方法拍我的脑袋?谢谢你们!
3 r" {3 ^! D& |! L0 u& V) X更新:5 p$ J1 |( u$ h! `! v5 Y
说明:
* I3 ~# n6 X$ M4 k/ v"1" &quotRIMARY"   ""    "ALL"   \N  \N  \N  \N  "3545"  "Using temporary; Using filesort"
& k: j9 k+ R9 w"2" "DERIVED"   "views" "index" \N  "page"  "5" \N  "196168"    "Using where"
2 G  _: v6 H7 A2 |模式:7 a& b* r, ^, h
ID       int(8) unsigned  (NULL)     NO      PRI     (NULL)   auto_increment  select,insert,update,references         - v* D- ]0 C2 t. Q6 U; z9 Q# d
page     int(8)           (NULL)     YES     MUL     (NULL)                   select,insert,update,references         - I2 |  e% h( Q; F, c5 Z0 x9 B2 t' s
user_id  int(8)           (NULL)     YES             (NULL)                   select,insert,update,references         
9 u2 h# j- l% h6 e( ]  w" R1 Y$ \' d  Esession  int(8)           (NULL)     YES             (NULL)                   select,insert,update,references         ' |0 {0 Q! c$ d" \/ @4 X
created  datetime         (NULL)     NO                                       select,insert,update,references
& ^* e# @5 \) a/ G索引信息:' L% t; g4 ?; P" {
views            0  PRIMARY              1  ID           A               196008    (NULL)  (NULL)          BTREE) {' P7 h% g7 Y) T/ M. Y
views            1  page                 1  page         A                  259    (NULL)  (NULL)  YES     BTREE
* _8 O8 I. ~( A; L1 H               
. T3 \; s& R/ v: l7 H2 b解决方案:1 c6 [" U* M( R/ A2 D
               
4 F  w+ K$ Z% V. y7 s8 y- z7 G$ S7 d5 ~1 n5 e/ m; [6 }* }
$ L6 W0 [; W" k, D7 w2 }
               
, n: o/ ^; G$ W我正在跟踪查看不同页面的视图,并且我想知道每个会话的最高页面,以便了解在任何给定条件下他们的点击量(从头到尾查看所有页面)会议。- a# a3 h8 W9 R3 {4 j+ h, m# z* t
4 \# }  R  k: x0 [* v1 t  O
分组之前先订购是一种非常不可靠的方法。0 `4 @. k- f3 @, t& x
MySQL扩展GROUP BY语法:您可以在SELECTandORDER BY子句中使用未分组和未聚合的字段。5 H& m. k. A) l
在这种情况下,page每个输出一个随机值session。
6 Z- k% [: c5 ^% e& m' |2 b- y9 t文档
+ ~' e" N8 l) ~! V# c! d明确指出,您永远不应对将确切确定为哪个值做任何假设:0 S0 a4 M9 T% T4 Q7 k7 W. g
8 N7 i, y6 L! t1 o! Y. E3 E( V6 w/ n$ O
如果您从GROUP
2 t- y' L3 k2 N: EBY零件中省略的列在组中不是恒定的,请不要使用此功能。服务器可以自由地从组中返回任何值,因此除非所有值都相同,否则结果是不确定的。
; G* T5 E. I) I: _' _7 J9 {' Q% C. D, R, Y3 p0 o# h) }
但是,实际上,将返回扫描的第一行中的值。* u; D& x9 i( h0 ^6 S. @0 O% f
由于您ORDER BY page DESC在子查询中使用,因此该行恰好是page每个会话最多的行。
' V7 X* s# R$ j0 V/ S" p2 s您不应该依赖它,因为此行为没有记录,并且如果在下一版本中将返回其他行,则不会将其视为错误。
" X2 N+ a& P4 H+ b$ Q. i' T1 K但是,您甚至不必做这些令人讨厌的把戏。- F% p# i. p/ n
只需使用聚合函数:% R' f& [9 l" r. V1 Z& n' V
SELECT  MAX(page)& w8 ^! ^' Y  l4 l* k
FROM    views/ f) l( q* j9 f. d: @
WHERE   user_id = '1'
5 \% k; g6 \9 eGROUP BY/ a- _& ^$ w5 L
        session
- g0 ~* D$ j0 ~' u  V0 {, o2 {这是记录在案的,干净的方法来做您想要的。  j, o; G' J8 i8 A+ T* ?
创建一个复合索引(user_id, session, page)以使查询运行更快。% ]* B5 q9 \7 p" a% o+ F$ B
如果您需要表中的所有列,而不仅是聚合的列,请使用以下语法:- {& o! U. h5 c$ Z; j' K
SELECT  v.*7 T$ c+ t2 |5 f! a
FROM    (1 p$ l, w) c: u+ I* Y3 k  ]
        SELECT  DISTINCT user_id, session
$ G# W' ?1 u, W  F$ l6 E        FROM    views! f4 x% J8 t$ }- P6 b3 y- u
        ) vo
" E/ ?2 k6 ]2 D/ t, ~2 WJOIN    views v) G& ?  T" L1 A' c- B
ON      v.id =
& C; i2 `8 M* q" K& m/ {        (7 w* F6 f8 e- l  r9 _; G: A; Y1 `
        SELECT  id, k: j, q, P$ E- W/ J3 \
        FROM    views vi& c  c* _' f; j, c2 G- @
        WHERE   vi.user_id = vo.user_id/ h9 _$ T5 ?2 ?! }/ n5 q& s4 a2 H) g
                AND vi.session = vo.session9 x8 X  d8 Q6 k" y+ c' A6 V1 u
        ORDER BY* U2 n: }4 O  ?8 b7 p
                page DESC
% ?1 y/ M: L8 a  X0 @. E# ]/ v. y        LIMIT 1
' T) J2 N1 |1 S        ), `6 u5 B% Z0 v1 W
这假设id是PRIMARY KEYon views。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则