我有一个具体化的路径驱动公告板。它使用以下查询按顺序获取消息,
SELECT * FROM Board ORDER by root DESC, path ASC LIMIT 0,100
其中 root
是线程根消息的 id
,path
是物化路径。
但是,我使这个查询使用索引的努力都没有取得任何成功。
mysql> explain extended select path from Board order by root desc, path asc limit 100;
+-------+---------------+----------+---------+------+-------+----------+----------------------------+
| type | possible_keys | key | key_len | ref | rows | filtered | Extra
+-------+---------------+----------+---------+------+-------+----------+-----------------------------
| index | NULL | rootpath | 261 | NULL | 21998 | 100.00 | Using index; Using filesort
目前它在 rows
列下显示表格中所有行的数量。我想知道,是否有办法减少该数量或以任何其他方式优化查询?
CREATE TABLE `Board` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`path` varchar(255) NOT NULL DEFAULT '0',
`root` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `root` (`root`),
KEY `path` (`path`),
KEY `rootpath` (`root`,`path`)
)
查询的主要问题是分页 - 我需要从上一页最后一页旁边的消息开始第二页。这就是为什么我想要它的直接方式 - 没有 subleects 和东西。
虽然当前设置不太好,因为它从线程的中间开始第二页,但至少它是合乎逻辑的。
最佳答案
您面临的问题在 this article 中得到了很好的解释。 .重要的部分是:
Most typical case is when you want to order by two colums in different directions: … ORDER BY price ASC, date DESC LIMIT 10 If you have indexed on (price,date) in ascending order you will not be able to optimize this query well – external sort (“filesort”) will be needed. If you would be able to build index on price ASC, date DESC the same query could retrive data in aready sorted order.
文章还提到了该问题的有效解决方法:将第二个“order”子句反转:
This is however something you can workaround by having something like “reverse_date” column and using it for sort. With MySQL 5.0 you even can use triggers to update it as real date updates so it becomes less ugly. In fact this is for example why you would see “reverse_timestamp” field in Wikipedia table structure.
同样来自官方MySQL documentation :
In some cases, MySQL cannot use indexes to resolve the ORDER BY, although it still uses indexes to find the rows that match the WHERE clause. These cases include the following:
.....
You mix ASC and DESC:
SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC;
作为建议,您最好有一个 reversed_root
列,它是 Integer.MAX_VALUE - root
并且在 (reversed_root, path) 上有一个索引。然后你可以有一个查询:
SELECT * FROM Board ORDER by reversed_root ASC,path ASC LIMIT 0,100
关于mysql - 是否可以让 MySQL 使用 1 DESC,2 ASC 的 ORDER 索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10382346/