我因为一个我无法优化的简单查询而陷入困境2天...... 我的表包含大约60,000,000行:
CREATE TABLE IF NOT EXISTS `pages_objects_likes` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`page_id` bigint(20) unsigned NOT NULL,
`object_id` bigint(20) unsigned NOT NULL,
`user_id` bigint(20) unsigned NOT NULL,
`created_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`),
KEY `pages_objects_likes_page_id_created_time_index` (`page_id`,`created_time`)
) ENGINE=InnoDB ;
我的查询是:
SELECT c.user_id, c.page_id,
COUNT(*) AS total
FROM pages_objects_likes c
WHERE page_id IN (116001391818501,37823307325,45502366281,30166294332,7133374462,223343965320,9654313055,123096413226,231809706871226,246637838754023,120063638018636)
AND created_time >= DATE_SUB('2014-06-30', INTERVAL 1 YEAR)
AND created_time < DATE_SUB('2014-06-30', INTERVAL 6 MONTH)
GROUP BY c.user_id, c.page_id
但当我EXPLAIN
时,我明白了:
Using index condition; Using temporary; Using filesort
我想优化索引或查询,因为它需要花费很长时间才能执行(超过5分钟)。 我的服务器有SSD,32Gb或RAM以及专用于MySQL的4 Core i5,因此它不是硬件问题:)
感谢您的帮助!
答案 0 :(得分:1)
好的,我找到了解决方案!
像这样更新索引:
KEY `pages_objects_likes_page_id_created_time_index` (`page_id`,`user_id`,`created_time`)
通过反转group by语句来更新查询:
GROUP BY c.page_id, c.user_id
索引现在随处可用;)
答案 1 :(得分:-1)
我猜你的问题是DATE_SUB函数,一般来说使用WHERE中的函数是个坏主意,因为
我的建议是从客户端传递DATE_SUB输出,或者在查询开始之前计算一次。
我也可能想在“created_time”,“page_id”,“user_id”上放一个索引,看看它是怎么回事。