假设我有一个包含 a、b 和 c 列的大型数据库。假设我希望根据多列上的某种顺序选择第 x 到第 (x+100) 行。我可以使用 ORDER BY
和 LIMIT
结构来完成此操作:
SELECT * FROM table_name ORDER BY b ASC, c DESC, a DESC LIMIT x, 100
如果我希望使用相同的顺序(b 升序,c 降序,然后 a 降序)但具有不同的范围限制来执行许多类似的查询,该怎么办?直观上,不需要为每个此类查询重复昂贵的排序操作。
我正在研究使用索引 ( http://dev.mysql.com/doc/refman/5.6/en/order-by-optimization.html ) 优化 ORDER BY
操作,但不幸的是,似乎不可能创建包含混合升序和降序的索引。
有没有好的方法来优化这个?这似乎是一个相当常见的用例。
最佳答案
可能唯一的优化是将数字 b
存储为 -b
或具有一个额外的列,其中冗余地包含 -b
它。然后
ORDER BY b ASC, c DESC LIMIT...
将被替换为
ORDER BY minusb DESC, c DESC LIMIT...
还有
INDEX(minusb, c)
只要你确定
- 所有
ORDER BY
项都是同一个表中的列名称, - 方向相同,
- 并且存在一个
INDEX
,它按照与ORDER BY
列表相同的顺序列出了所有这些内容(可以选择在末尾添加额外的列) ,
那么优化器可以(但可能选择不)非常有效地使用该INDEX
——包括使用LIMIT
。
将它们全部设为 ASC
还是全部设为 DESC
并不重要。 (ASC
可能稍微好一些。)
请记住,LIMIT m, n
必须读取 m+n
行。 (OFFSET
是一个不错的功能,但没有得到很好的优化。)如果您使用 OFFSET
和 LIMIT
对长列表进行“分页” ,最好“记住您离开的位置”以避免扫描 OFFSET
行。 (如果适用,我可以为您提供更多详细信息。)
关于mysql - 如何优化MySQL重复排序选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31169728/