我遇到以下查询的问题非常慢:
SELECT A.* FROM B INNER JOIN A ON A.id=B.fk_A WHERE A.creationDate BETWEEN '20120309' AND '20120607' GROUP BY A.id ORDER BY RAND() LIMIT 0,5
EXPLAIN:
id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE B index fk_A fk_A 4 \N 58962 Using index; Using temporary; Using filesort 1 SIMPLE A eq_ref PRIMARY,creationDate PRIMARY 4 B.fk_A 1 Using where
指数:
A.id (int) = PRIMARY index A.creationDate (date) = index B.fk_A = index
你看到要优化的东西吗?
非常感谢您的建议
答案 0 :(得分:1)
我认为RAND()函数会为每一行创建一个Rand()值(这就是using temporary
显示的原因,而filesort
因为它不能使用索引。
最好的方法是SELECT MAX(id) FROM a
获取最大值。
然后在1和MAX之间创建5个随机数(id)并进行SELECT ... WHERE a.id IN (...)
查询。
如果结果少于5行(因为已删除记录),请重复此过程直到您没事(或者最初创建100个随机数并将查询限制为5。
这不是100%的mysql解决方案,因为你必须在你的代码中执行逻辑,但我相信会更快。
<强>更新强> 刚刚在网上找到一篇有趣的文章,基本上讲的是:http://akinas.com/pages/en/blog/mysql_random_row/
答案 1 :(得分:1)
可能重写查询:
SELECT A.*
FROM A
WHERE A.creationDate BETWEEN '20120309' AND '20120607'
AND EXISTS
( SELECT *
FROM B
WHERE A.id = B.fk_A
)
ORDER BY RAND()
LIMIT 0,5