0

我有一个使用 order by 将数据返回到用户界面的系统;用户可以按任何顺序从十几个不同的排序选项中进行选择。

我有查询

explain extended select t.* from task t order by create_date, due_date limit 5;

+------+-------------+-------+------+---------------+------+---------+------+--------+----------+----------------+
| id   | select_type | table | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra          |
+------+-------------+-------+------+---------------+------+---------+------+--------+----------+----------------+
|    1 | SIMPLE      | t     | ALL  | NULL          | NULL | NULL    | NULL | 331233 |   100.00 | Using filesort |
+------+-------------+-------+------+---------------+------+---------+------+--------+----------+----------------+
1 row in set, 1 warning (0.00 sec)

我有一个关于 create_date 和 due_date 的索引。我知道我可以创建一个多列索引;但是,由于大约有 12 种不同的排序选项,这意味着我必须创建一百多个索引来涵盖所有场景。

我阅读了有关索引合并的信息,我相信这会解决问题,因为我可以为您可以排序的每一列创建一个索引,但是我似乎无法让它在查询的“排序依据”部分工作。

4

3 回答 3

1

即使没有索引,DBMS 也非常擅长排序。请记住,额外的索引会减慢更新操作的速度,因此表上肯定会出现“索引过多”这样的情况。

如果查询很复杂,则无法保证可以使用索引呈现数据,或者使用索引是最快的查询计划。

例如,您可能在 ColumnA 上有一个非常好的过滤条件(它只选择表中百万行的 1/1000),而您想对 ColumnB 和 ColumnC 进行排序。在这种情况下,优化器可能会使用 ColumnA 上的索引并对 1000 个结果行进行排序,而不是按照 ColumnB 和 ColumnC 上的索引顺序读取整个 1,000,000 行表并在 1000 行中选择满足过滤条件。

通常,优化器比你更清楚。不总是; 实施中甚至偶尔会出现错误,有时甚至会出现疏忽。但是作为第一条经验法则,除非您可以重写查询以从根本上更快地获得相同的结果,否则优化器可能会做得不错。(如果您可以重写查询并更快地获得结果,那么优化器已经搞砸了,并且您已经为错误报告奠定了良好的基础。)

于 2013-01-12T05:28:45.830 回答
0

试试这个解决方法:

explain extended select * from (select t.* from task t order by create_date limit 30) z order by create_date, due_date limit 5;

当您的所有行都在前 30 行内时,它可以工作,同时使用第一顺序。

“技巧”是从主表中选择一个简单的查询,并在 30 行集合上做更大的事情(连接、高级订单、随机等),这比使用整个 330K 行表要快。

于 2013-02-07T11:02:22.517 回答
0

你唯一能做的就是强制索引

强制索引 index_name 为 order by

如果您想利用索引合并,请尝试使用联合或等,这将使您使用多索引

永远记住,当两个条件相互独立时,将使用多重索引,那么只有它才会起作用

在极少数情况下,可以使用多索引

(这里对于上面的查询我相信它不会工作)

于 2013-01-12T06:39:58.963 回答