以下查询相对较慢(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。
答案 0 :(得分:5)
索引可能会影响ORDER BY
子句的性能。这MySQL manual page可能值得你花时间。从本质上讲,如果您按照MySQL用于查询的索引的一部分进行排序,MySQL可以使用索引进行排序而不是数据本身。
在您的特定查询中,DATE
列具有索引的事实并不重要,因为该索引可能未在您的查询中使用。您的WHERE
语句包含items.ACTIVE
和items.DELETED_AT
,如果这些列的索引用于不包含WHERE
列的DATE
,然后MySQL不能使用索引按DATE
排序,并且很可能采用文件排序。
如果您能够提出可供WHERE
和ORDER 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)
这些是可能(无法保证阅读)的帮助。
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