我有这张桌子:
+---------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+--------------+------+-----+---------+----------------+
| ID | bigint(20) | NO | PRI | NULL | auto_increment |
| CODE | varchar(255) | NO | | NULL | |
| REVISION | varchar(255) | NO | | NULL | |
| NAME | varchar(255) | NO | | NULL | |
+---------------------+--------------+------+-----+---------+----------------+
现在,我的应用会执行这些查询(更有可能发生这种情况):
SELECT * FROM ITEM WHERE ID = ?
SELECT * FROM ITEM WHERE CODE = ? ORDER BY REVISION DESC
SELECT * FROM ITEM WHERE CODE = ? AND REVISION = ?
SELECT * FROM ITEM WHERE CODE LIKE ? OR NAME LIKE ? ORDER BY CODE ASC, REVISION DESC
这种情况的最佳索引组合是什么?
我在Windows 8.1 x64上使用MySQL 5.6.14(InnoDB)。
更新(仍在测试中):
目前为止最好的方法是使用单独的索引:IDX_CODE(CODE),IDX_NAME(NAME)。
mysql> describe select id, code, revision from UNIT where code like 'M0170SIGM1%' or name like 'M0170SIGM1%' ORDER BY code ASC, revision DESC;
+----+-------------+-------+-------------+-------------------+-------------------+---------+------+------+------------------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------------+-------------------+-------------------+---------+------+------+------------------------------------------------------------------+
| 1 | SIMPLE | UNIT | index_merge | IDX_CODE,IDX_NAME | IDX_CODE,IDX_NAME | 767,767 | NULL | 31 | Using sort_union(IDX_CODE,IDX_NAME); Using where; Using filesort |
+----+-------------+-------+-------------+-------------------+-------------------+---------+------+------+------------------------------------------------------------------+
无法让MySQL在双向排序中使用索引。
答案 0 :(得分:1)
主键负责第一个查询。
对于第二个和第三个:item(code, revision)
。请注意,order by case asc
是不必要的,因为您只选择一个代码。
最后一个查询有问题。您可能想要使用全文索引。如果like
实习生在开始时没有外卡,那么以下表格可能会更好:
select i.*
from (select i.* from item i where code like ? union
select i.* from item i where name like ?
) i
order by code, revision;
但是,引擎可能会使用全表扫描然后进行排序来实现此查询,而不管索引如何。
答案 1 :(得分:1)
对于第四种混合asc / desc命令的情况,它可能无法完全使用索引,因为mysql似乎不支持这种组合:
Order-By-Optimization in mysql
在某些情况下,MySQL无法使用索引来解析ORDER BY, 虽然它仍然使用索引来查找与WHERE匹配的行 条款。这些案例包括以下内容:
... You mix ASC and DESC: SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC;
该问题的可能解决方案:
如果您的修订版本只是一个正整数,您可以使用该值乘以-1的另一列,并按此列DESC排序,这将允许您在这两列上使用索引,因为它们将具有同样的方向......在这里像一个带有时间戳列的魅力......