我有一个使用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”部分工作查询。
答案 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行表更快。