MySQL:定义正确的索引

时间:2014-11-03 12:46:36

标签: mysql indexing

我有这张桌子:

+---------------------+--------------+------+-----+---------+----------------+
| 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    |                |
+---------------------+--------------+------+-----+---------+----------------+

现在,我的应用会执行这些查询(更有可能发生这种情况):

  1. SELECT * FROM ITEM WHERE ID = ?
  2. SELECT * FROM ITEM WHERE CODE = ? ORDER BY REVISION DESC
  3. SELECT * FROM ITEM WHERE CODE = ? AND REVISION = ?
  4. SELECT * FROM ITEM WHERE CODE LIKE ? OR NAME LIKE ? ORDER BY CODE ASC, REVISION DESC
  5. 这种情况的最佳索引组合是什么?

    我在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在双向排序中使用索引。

2 个答案:

答案 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排序,这将允许您在这两列上使用索引,因为它们将具有同样的方向......在这里像一个带有时间戳列的魅力......