MySQL使用多个索引按顺序排列

时间:2013-01-12 04:17:05

标签: mysql sql indexing mariadb

我有一个使用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种不同的排序选项,这意味着我必须创建超过100个索引才能涵盖所有场景。

我读到有关索引合并的内容,我相信这样可以解决问题,因为我可以为每个列创建索引,但是我似乎无法让它在“order by”部分工作查询。

3 个答案:

答案 0 :(得分:1)

即使没有索引,DBMS也非常擅长排序。请记住,额外的索引会降低更新操作的速度,因此桌面上肯定存在“索引太多”这样的事情。

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

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

通常,优化器比您更了解。不总是;实施中甚至偶尔会出现漏洞,有时会出现疏忽。但作为第一个经验法则,除非您可以重写查询以更快地获得相同的结果,否则优化器可能会做得不错。 (如果您可以重写查询并更快地获得结果,那么优化器已经破坏了它,并且您已经为错误报告提供了良好的基础。)

答案 1 :(得分:0)

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

按订单强制索引index_name

如果你想利用索引合并的优势 然后尝试使用union,或者等,这将使你使用多索引

请记住,当两个条件彼此独立然后只能使用时,将使用多索引

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

(这里针对上述查询,我​​相信它不会起作用)

答案 2 :(得分: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行中时,它可以正常工作。

" Trick"从主表中选择一个simle查询,并在30行集上执行更大的事情(连接,高级订单,随机等),这比使用整个330K行表更快。