1

我对以下非常慢的查询有疑问:

    从 B 中选择 A.*  
    A.id=B.fk_A 上的内部连接  
    WHERE A.creationDate BETWEEN '20120309' AND '20120607'  
    按 A.id 分组  
    兰德订购()
    限制 0,5

解释 :

    id select_type table type possible_keys key key_len ref rows Extra
    1 SIMPLE B 索引 fk_A fk_A 4 \N 58962 使用索引;使用临时的;使用文件排序
    1 SIMPLE A eq_ref PRIMARY,creationDate PRIMARY 4 B.fk_A 1 使用 where

索引:

    A.id (int) = PRIMARY 索引
    A.creationDate(日期)=索引
    B.fk_A = 索引

你有什么要优化的吗?

非常感谢您的建议

4

2 回答 2

1

我认为 RAND() 函数将为每一行创建一个 Rand() 值(这就是using temporary显示的原因,filesort因为它不能使用索引。

最好的方法是SELECT MAX(id) FROM a获得最大值。然后在 1 和 MAX(id) 之间创建 5 个随机数并进行SELECT ... WHERE a.id IN (...)查询。

如果结果少于 5 行(因为一条记录已被删除),则重复该过程,直到您没问题(或最初创建 100 个随机数并将查询限制为 5。

这不是 100% 的 mysql 解决方案,因为您必须在代码中执行逻辑,但我相信会快得多。

更新 刚刚在网上找到了一篇有趣的文章,基本上是一样的: http: //akinas.com/pages/en/blog/mysql_random_row/

于 2012-06-08T07:50:45.887 回答
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
于 2012-06-08T09:14:18.300 回答