2014-11-03 61 views
0

我有这个表:MySQL的:确定正确的索引

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

对于这种情况,索引的最佳组合是什么?

我在Windows 8.1 x64上使用MySQL 5.6.14(InnoDB)。


UPDATE(仍在测试):

迄今最好使用单独的索引: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

你是什么引擎innodb,myisam,档案或其他东西 – gvgvgvijayan 2014-11-03 12:51:23

+0

InnoDB,对不起,我忘了提及 – 2014-11-03 12:53:00

+0

你的应用程序执行插入?并且LIKE查询的开头是否会出现通配符? – Strawberry 2014-11-03 13:24:46

回答

1

主键处理第一个查询。

第二和第三:item(code, revision)。请注意,order by case asc是不必要的,因为您只选择一个代码。

最后一个查询有问题。您可能想要使用全文索引。如果like attern是没有在一开始外卡,那么下面的配方可能会更好:

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; 

然而,发动机很可能将实现使用全表此查询扫描,然后排序,而不管索引。

+0

感谢您的回应。我纠正了查询2和3.类似'attern'可能是'somevalue%',但我使用JPA,我还不知道如何使它在DDL自动生成中声明全文索引。 'item(code,revision,name)'在第4个查询中有帮助吗? – 2014-11-03 13:01:49

+0

@MicheleMariotti。 。 。有可能SQL引擎可以使用'order by'索引,然后逐行进行比较。我不认为MySQL会这样做,但我不是100%确定的。 – 2014-11-03 14:29:21

1

为了您与混合递增/递减顺序从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,并按这个列的顺序排序,这将允许你在这两列上使用索引,因为它们会有相同的方向......在这里工作就像一个有时间戳列的魅力......

+0

谢谢,但不幸的是它不是一个数字。 – 2014-11-03 15:01:27