2014-11-03 44 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