【问题标题】:MySQL query optimisation with group by and order by randMySQL 查询优化与 group by 和 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?

标签: mysql optimization


【解决方案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/

【讨论】:

    猜你喜欢
    • 2012-12-31
    • 1970-01-01
    • 2012-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-11
    相关资源
    最近更新 更多