MySQL 查询优化与 group by 和 order by rand

Posted

技术标签:

【中文标题】MySQL 查询优化与 group by 和 order by rand【英文标题】:MySQL query optimisation with group by and order by rand 【发布时间】:2012-06-12 06:29:37 【问题描述】:

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

从 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 = 索引

你有什么需要优化的地方吗?

非常感谢您的建议

【问题讨论】:

是 MyISAM 还是 InnoDB 表? 返回多少行 - 如果您删除 LIMIT? 【参考方案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

【讨论】:

你能解释一下你在查询中做了什么吗?谢谢【参考方案2】:

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

最好的方法是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/

【讨论】:

以上是关于MySQL 查询优化与 group by 和 order by rand的主要内容,如果未能解决你的问题,请参考以下文章

具有 JOIN 和 GROUP BY 优化的 MySQL 查询。是不是可以?

MySQL 查询优化 Group By with Max

MySQL调优--05---多表查询优化子查询优化 ORDER BY优化GROUP BY优化分页查询优化

使用 GROUP BY ... HAVING 优化 MySQL 查询时遇到问题

MySQL从入门到精通高级篇(二十八)子查询优化,排序优化,GROUP BY优化和分页查询优化

MySQL从入门到精通高级篇(二十八)子查询优化,排序优化,GROUP BY优化和分页查询优化