MySQL缓慢分组/顺序

时间:2011-12-25 20:47:37

标签: mysql performance join sql-order-by

以下查询相对较慢(0.7秒,行数约为6k)

SELECT items.*, COUNT(transactions.ID)
   FROM items
  INNER JOIN users ON (items.USER = users.ID)
   LEFT JOIN transactions ON (items.id = transactions.item)
  WHERE items.ACTIVE = 1
    AND items.DELETED_AT IS NULL
  GROUP BY items.ID
  ORDER BY items.DATE DESC
  LIMIT 20

但是当按items.ID DESC而不是items.DATE排序时,速度会急剧加快。事务连接是一个大表(~250k行)并且是一对多的。日期列有一个索引。

有没有办法一般性地提高ORDER BY的性能?

编辑:items.user,transactions.item和items.date上的索引。项目有49列,用户76和事务17。

3 个答案:

答案 0 :(得分:5)

索引可能会影响ORDER BY子句的性能。这MySQL manual page可能值得你花时间。从本质上讲,如果您按照MySQL用于查询的索引的一部分进行排序,MySQL可以使用索引进行排序而不是数据本身。

在您的特定查询中,DATE列具有索引的事实并不重要,因为该索引可能未在您的查询中使用。您的WHERE语句包含items.ACTIVEitems.DELETED_AT,如果这些列的索引用于不包含WHERE列的DATE,然后MySQL不能使用索引按DATE排序,并且很可能采用文件排序。

如果您能够提出可供WHEREORDER BY使用的索引,则可以获得优化提升。在这种情况下,items.ACTIVE似乎是一个低基数列,因此假设items.DELETED_AT是一个日期,我可能会为该表尝试类似INDEX(DELETED_AT,DATE)的索引。

使用EXPLAIN SELECT...了解更多有关正在发生的事情的信息,您可能会获得进一步的见解。

答案 1 :(得分:2)

SELECT * FROM(SELECT * FROM wp_users WHERE 1 GROUP BY ID limit 0,10)as X ORDER BY ID DESC

以上查询工作正常,我在很长的数据库中使用它。它按照我们从内部选择查询获得的10个OR(xx)项目的列表进行排序,因此它非常快!

答案 2 :(得分:0)

这些是可能(无法保证阅读)的帮助。

  1. 消除项目上的*。*并单独列出每个字段。 49 列很多你真的需要它们吗?
  2. 通常,引擎会优化查询以限制 在连接上考虑标准。也许是使用的计划 引擎没有这样做(需要解释计划结果才知道)所以 重新安排where子句并加入MAY(不太可能)帮助 迫使引擎考虑这一点。 (见下文)
  3. 如果有许多更新,插入,删除,则重建表统计信息 随着时间的推移,表统计数据可能会关闭 需要 rebuilt 对于每个表
  4. SELECT items.[list fields], COUNT(transactions.ID)
       FROM items
      INNER JOIN users ON (items.USER = users.ID)
            AND items.Active=1 
            AND items.DELETED_AT is Null
       LEFT JOIN transactions ON (items.id = transactions.item)
      GROUP BY items.ID
      ORDER BY items.DATE DESC
      LIMIT 20