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

Какова наилучшая комбинация индексов для такого сценария?

Я использую MySQL 5.6.14 (InnoDB) для Windows 8.1 x64.


UPDATE (по-прежнему тестирования):

Лучшие до сих пор с использованием отдельных индексов: IDX_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

+0

InnoDB, извините, я забыл упомянуть –

+0

Выполняет ли ваше приложение вставки? И может ли подстановочный знак появляться в начале запроса LIKE? – Strawberry

ответ

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. Похоже, что 'like' attern будет' somevalue% ', но я использую JPA, и я еще не знаю, как заставить его объявлять полные текстовые индексы в генерации DDL. Будет ли «item (code, revision, name)» некоторая помощь в 4-м запросе? –

+0

@ MicheleMariotti. , , Возможно, что SQL-движок мог использовать индекс для 'order by', а затем выполнить сравнение по строкам. Я не думаю, что MySQL это сделает, но я не уверен на 100%. –

1

Для вашего четвертого случая со смешанным Asc/порядка по убыванию она может завершиться неудачей полностью использовать индекс, так как 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, который позволит вам использовать индекс для этих двух столбцов, так как они будут иметь одно и то же направление ... работает здесь как шарм с колонкой timestamp ...

+0

Спасибо, но, к сожалению, это не число. –

Смежные вопросы