mysql - 是否可以让 MySQL 使用 1 DESC,2 ASC 的 ORDER 索引?

标签 mysql indexing materialized-path-pattern

我有一个具体化的路径驱动公告板。它使用以下查询按顺序获取消息,

SELECT * FROM Board ORDER by root DESC, path ASC LIMIT 0,100

其中 root 是线程根消息的 idpath 是物化路径。

但是,我使这个查询使用索引的努力都没有取得任何成功。

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/

相关文章:

mysql - c3p0 连接池总是达到最大

php - 远程数据库的记录为空

mongodb - 当字段不为空时创建部分索引

r - 通过使用另一列索引到列表中来在数据框中创建一个新列?

python - 列表索引超出范围,python

php - 根据mysql中的路径选择

jquery - x 轴上显示时间,而不是 highstock 中显示日期

php - 在单个查询中选择的安全行数

mysql - 如何正确排序 SQL 中的物化路径?

android - 仅从具有物化路径的表中选择直接后代