回答

收藏

如何在MySQL中通过连接提高性能的顺序

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

我正在开发一个社交网络跟踪应用程序。即使连接正确,也可以正常工作。但是,当我添加order by子句时,总查询执行时间要长100倍。我用于获取不带order$ A' C/ {+ a" \+ x1 Y" o. {
by子句的twitter_users的以下查询。
* A( A9 C& u, U! E; gSELECT DISTINCT  `tracked_twitter`.id
7 l: v: t. f# R9 y0 K7 h8 bFROM tracked_twitter# e  ?! j2 \- P. s  @8 X
INNER JOIN  `twitter_content` ON  `tracked_twitter`.`id` = `twitter_content`.`tracked_twitter_id` , G$ L( S$ m' h. g
INNER JOIN  `tracker_twitter_content` ON  `twitter_content`.`id` = `tracker_twitter_content`.`twitter_content_id`
2 T4 x+ `& Q6 z8 k$ eAND  `tracker_twitter_content`.`tracker_id` =  '88'8 A4 k% P# [8 o( E5 C( Q) D
LIMIT 20# {' N0 p- a% E2 t6 l. P% Z
显示第0-19行(共20行,查询耗时0.0714秒)
8 T; B: b3 g4 Z* I) i9 X但是当我添加order by子句(在索引列上)时
3 s9 [+ g0 W3 w1 ?" VSELECT DISTINCT  `tracked_twitter`.id
3 n# u: @& n8 I: F0 WFROM tracked_twitter
+ O1 l* E0 X! G9 J: t: E4 x" RINNER JOIN  `twitter_content` ON  `tracked_twitter`.`id` =  `twitter_content`.`tracked_twitter_id` , h+ w& N6 K& B, o/ e, F) a
INNER JOIN  `tracker_twitter_content` ON  `twitter_content`.`id` =  `tracker_twitter_content`.`twitter_content_id`
' ]! U( z5 J  Z2 GAND  `tracker_twitter_content`.`tracker_id` =  '88'- V) X# p% D1 u0 v% u3 D0 g8 q
ORDER BY tracked_twitter.followers_count DESC
/ ]! l  a0 Q  F0 q" U8 k2 ALIMIT 20+ [8 Q3 ]+ e9 y+ V, E) d9 l' z7 V
显示第0-19行(共20行,查询耗时13.4636秒)  J/ A) k) v6 S3 t$ b
解释& C, N& ^6 d# t' {; P
3 T8 i8 D' A3 }! ]4 x& l

& N5 i+ k+ g+ c2 c+ ^" y0 V  [) g1 z. o3 T/ d$ }
当我仅在其表中实现order by子句时,不会花费太多时间
# G; `! `( R. b0 ~/ W5 tSELECT * FROM `tracked_twitter` WHERE 1 order by `followers_count` desc limit 20
1 g$ F- \9 M. M' J显示第0-19行(共20行,查询耗时0.0711秒)[followers_count:68236387-10525612]! B. \% H* ]2 X2 O
表创建查询如下4 L# P1 g# o: t* Z. F8 C' p: }
CREATE TABLE IF NOT EXISTS `tracked_twitter` (
2 @& f$ [, o$ w5 T    `id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
- Z  Q8 k; O& f0 ?: l9 X    `handle` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
3 {$ P9 F; b8 e8 ~/ c1 p" q    `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,3 A$ ^% R" @( @5 p+ A0 r" h
    `location` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,; h4 m& S* T$ @
    `description` text COLLATE utf8_unicode_ci,' u0 t# W1 E' @! S2 m0 d, R
    `profile_image` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
8 f' p3 T6 R9 _+ x/ j    `followers_count` int(11) NOT NULL,% k6 b, B/ C1 q7 ?, W6 y
    `is_influencer` tinyint(1) NOT NULL DEFAULT '0',
- x  w7 [% N  w9 O- M' k  B% h" R    `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
9 ~3 a" j, b5 b9 t* c+ J    `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
& d8 d& `1 O9 L0 S$ ?; _' M8 C    `gender` enum('Male','Female','Other') COLLATE utf8_unicode_ci ' w8 O' X* S7 G, F
     DEFAULT NULL,8 z( g/ e  K, [& u, L
     PRIMARY KEY (`id`)," w: R6 a* a+ u+ m2 C0 ?
     KEY `followers_count` (`followers_count`)
0 Y3 B5 E! p. A& P+ O8 O) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
* S- H5 x8 \+ J& F因此,当我在其表上执行它时,join并不会因工作良好而减慢查询和排序的速度。那么如何提高性能呢?4 Y% E  k4 a! ~$ k5 p2 y5 Z  z# z
更新1
9 k! J$ O- ^6 b7 H% A' y0 k" _@GordonLinoff方法解决是否只需要父表的结果集。我想知道每人tweets的数量(与tracked_twitter表匹配的twitter_content的数量)。我该如何修改?如果我想在推文内容上使用数学函数,该怎么做?
4 e$ e, A( o2 w; ]2 g% I& {! ZSELECT  `tracked_twitter` . * , COUNT( * ) AS twitterContentCount, retweet_count + favourite_count + reply_count AS engagement
& C0 u) k2 w# V1 }FROM  `tracked_twitter` 0 S. _+ J. R/ v- |1 a
INNER JOIN  `twitter_content` ON  `tracked_twitter`.`id` =  `twitter_content`.`tracked_twitter_id`
2 g4 X) q8 l$ B1 |5 L- r( fINNER JOIN  `tracker_twitter_content` ON  `twitter_content`.`id` =  `tracker_twitter_content`.`twitter_content_id` 3 W4 A7 C* k) K. g, ^
WHERE  `is_influencer` !=  '1'
  }2 O" D/ X1 x& \( oAND  `tracker_twitter_content`.`tracker_id` =  '88'
+ `, S  M. w. h" v5 ?AND  `tracked_twitter_id` !=  '0'
2 e9 `" L8 \5 y# iGROUP BY  `tracked_twitter`.`id` 2 E7 W5 @/ A& u1 r" C
ORDER BY twitterContentCount DESC * S1 C  m9 h& M. @" _3 Y
LIMIT 20 ( E4 o+ n( @9 g1 b0 \' e
OFFSET 0) f' @" ^% u1 k0 m8 k3 q: i) d
               
; ]2 |# N7 Y& o* F解决方案:* W% v4 B2 h& L/ ^/ P1 ^3 }
                ) @  f& o1 R9 |4 J5 a6 H
% v1 h) Y6 B" B( l+ E9 |
. L. \% @( k1 T4 U( E+ D
                尝试摆脱distinct。那是性能杀手。我不确定为什么您的第一个查询会很快工作;也许MySQL足够聪明,可以对其进行优化。
. I5 L+ ]: i9 e% G- K' z( y/ ~我会尝试:
7 h* l' ^3 G' t( ~, N1 s% U8 n( N* ^  NSELECT tt.id
* W* m% V# n! K; l% M* CFROM tracked_twitter tt
) `6 Z0 _' n6 @: p0 x" }+ {. hWHERE EXISTS (SELECT 1  {1 z# X7 {: r+ I/ \, r
              FROM twitter_content tc INNER JOIN  0 E" w7 K& v  i; E' V) S
                   tracker_twitter_content ttc
& @# E! G2 C. F+ _                   ON  tc.id =  ttc.twitter_content_id
2 g/ ]: ^2 m# W2 C  g              WHERE  ttc.tracker_id =  88 AND6 q' N/ m7 |3 r3 M
                     tt.id =  tc.tracked_twitter_id6 X  K& {# Z0 ~7 P& b' O) Q4 w$ y
             )0 z% s$ O- w2 g+ @
ORDER BY tt.followers_count DESC ;
- b+ v0 Q& k0 d+ u3 R: M5 ]对于此版本,您想对指数: tracked_twitter(followers_count,
7 }: M4 w' b& A" Vid),twitter_content(tracked_twitter_id, id),和5 m" v- V4 {* c8 b8 g' P
tracker_twitter_content(twitter_content_id, tracker_id)。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则