【发布时间】:2017-09-05 10:57:58
【问题描述】:
我正在开发一个社交网络跟踪应用程序。即使是连接也可以在适当的索引下正常工作。但是当我添加 order by 子句时,总查询的执行时间要长 100 倍。以下查询是我用来获取没有 order by 子句的 twitter_users 的。
SELECT DISTINCT `tracked_twitter`.id
FROM tracked_twitter
INNER JOIN `twitter_content` ON `tracked_twitter`.`id` = `twitter_content`.`tracked_twitter_id`
INNER JOIN `tracker_twitter_content` ON `twitter_content`.`id` = `tracker_twitter_content`.`twitter_content_id`
AND `tracker_twitter_content`.`tracker_id` = '88'
LIMIT 20
显示第 0 - 19 行(共 20 行,查询耗时 0.0714 秒)
但是当我添加 order by 子句(在索引列上)
SELECT DISTINCT `tracked_twitter`.id
FROM tracked_twitter
INNER JOIN `twitter_content` ON `tracked_twitter`.`id` = `twitter_content`.`tracked_twitter_id`
INNER JOIN `tracker_twitter_content` ON `twitter_content`.`id` = `tracker_twitter_content`.`twitter_content_id`
AND `tracker_twitter_content`.`tracker_id` = '88'
ORDER BY tracked_twitter.followers_count DESC
LIMIT 20
显示第 0 - 19 行(共 20 行,查询耗时 13.4636 秒)
当我单独在其表中实现 order by 子句时,不需要太多时间
SELECT * FROM `tracked_twitter` WHERE 1 order by `followers_count` desc limit 20
显示第 0 - 19 行(共 20 行,查询耗时 0.0711 秒)[followers_count: 68236387 - 10525612]
建表查询如下
CREATE TABLE IF NOT EXISTS `tracked_twitter` (
`id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`handle` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`location` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`description` text COLLATE utf8_unicode_ci,
`profile_image` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`followers_count` int(11) NOT NULL,
`is_influencer` tinyint(1) NOT NULL DEFAULT '0',
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`gender` enum('Male','Female','Other') COLLATE utf8_unicode_ci
DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `followers_count` (`followers_count`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
所以当我在它的表上执行它时,join 并没有因为运行良好而减慢查询和排序。那么如何提高性能呢?
更新 1
@GordonLinoff 方法解决了我是否只需要父表中的结果集。我想知道每人的推文数量(与 tracked_twitter 表匹配的 twitter_content 计数)。我该如何修改它?如果我想对推文内容进行数学运算,我该怎么做??
SELECT `tracked_twitter` . * , COUNT( * ) AS twitterContentCount, retweet_count + favourite_count + reply_count AS engagement
FROM `tracked_twitter`
INNER JOIN `twitter_content` ON `tracked_twitter`.`id` = `twitter_content`.`tracked_twitter_id`
INNER JOIN `tracker_twitter_content` ON `twitter_content`.`id` = `tracker_twitter_content`.`twitter_content_id`
WHERE `is_influencer` != '1'
AND `tracker_twitter_content`.`tracker_id` = '88'
AND `tracked_twitter_id` != '0'
GROUP BY `tracked_twitter`.`id`
ORDER BY twitterContentCount DESC
LIMIT 20
OFFSET 0
【问题讨论】:
-
如果删除
LIMIT-clause,无序查询需要多长时间?LIMIT在无序结果集中基本上意味着“给我一些符合我标准的 20 条记录”,而在有序结果中它意味着“给我找符合我标准的前 20 条记录”,这基本上意味着你必须识别所有其中。 -
EXPLAIN在查询中的输出是什么? -
@raina77ow 我添加了有问题的解释图片
-
其他两张表请提供
SHOW CREATE TABLE。听起来您好像缺少INDEX(tracker_id)。有关如何使 many:many 高效的信息,请参阅此内容:mysql.rjweb.org/doc.php/…
标签: mysql sql performance sql-order-by inner-join