【发布时间】:2012-03-13 04:43:22
【问题描述】:
我在使用 MySQL 查询时遇到了麻烦。我周末的大部分时间和今天的大部分时间都在试图让这个查询运行得更快一些。我已经把它做得更快了,但我知道我可以做得更好。
SELECT m.id,other_fields,C.contacts_count FROM marketingDatabase AS m
LEFT OUTER JOIN
(SELECT COUNT(*) as contacts_count, rid
FROM contacts
WHERE status = 'Active' AND install_id = 'XXXX' GROUP BY rid) as C
ON C.rid = m.id
WHERE (RAND()*2612<50)
AND do_not_call != 'true'
AND `ACTUAL SALES VOLUME` >= '800000'
AND `ACTUAL SALES VOLUME` <= '1200000'
AND status = 'Pending'
AND install_id = 'XXXXX'
ORDER BY RAND()
我在“install_id”、“category”和“status”上有一个索引,但 EXPLAIN 显示它是根据 9100 行排序的。
我的解释在这里: https://s3.amazonaws.com/jas-so-question/Screen+Shot+2012-03-13+at+12.34.04+AM.png
有人对我可以做些什么来加快速度有什么建议吗?查询的全部要点是从帐户记录 (install_id) 中选择一条随机记录,该记录与销售量、状态和 do_not_call 等特定条件相匹配。我目前正在收集 25 条记录并将其缓存(使用 PHP),因此我只需每 25 个请求运行一次此查询,但我已经每天处理数千个请求。当前运行需要 0.2 秒。我意识到通过使用 ORDER BY RAND() 已经对性能造成重大影响,但它只是对 25 行进行排序。
提前感谢您的帮助。
**编辑:我忘了提到'contact_sort' 索引在'contacts' 表上,并且索引 install_id、status 和 rid。 (rid 引用了 marketingDatabase 中的记录 ID,因此它知道联系人属于哪条记录。
**编辑2:查询中的2612数字代表marketingDatabase中符合条件(install_id、status、实际销量等)的行数
【问题讨论】:
-
看看dev.mysql.com/doc/refman/5.0/en/group-by-optimization.html 使用 GROUP BY 和索引时会出现限制和复杂性。引用手册“对 GROUP BY 使用索引的最重要的先决条件是所有 GROUP BY 列都引用来自同一索引的属性,并且索引按顺序存储其键(例如,这是 BTREE 索引而不是 HASH指数)。”您正在按非索引字段进行分组,并且还在子查询中选择和排序整个表。我认为(不确定)按 RAND() 排序也是一个坏主意。
-
ORDER BY RAND() 非常非常bad idea。
-
是的,我知道这是个坏主意,虽然我读过因为 ORDER BY RAND() 只订购 25 行,这没什么大不了的。我错了吗?我应该如何修复它并仍然获得随机记录?我没有任何无间隙自动递增的列...我的 id 列是自动递增的,但在行已被删除的地方有间隙。
-
我认为
WHERE (RAND()*2612<50)意味着MySQL仍然需要为表中的每一行计算一个随机值。大概这就是导致查询如此缓慢的原因? -
看看这个可能会给你一些启发stackoverflow.com/questions/31495446/…