Влияет ли оптимизация ORDER BY на следующую инструкцию SELECT? - PullRequest
5 голосов
/ 22 декабря 2011

У меня есть SELECT оператор, который я хотел бы оптимизировать. mysql - порядок по оптимизации говорит, что в некоторых случаях индекс нельзя использовать для оптимизации ORDER BY.В частности, точка:

Вы используете ORDER BY на непоследовательных частях ключаSELECT * FROM t1 WHERE key2 = константа ORDER BY key_part2;

заставляет меня думать, что это может быть так.Я использую следующие индексы:

UNIQUE KEY `met_value_index1` (`RTU_NB`,`DATETIME`,`MP_NB`),
KEY `met_value_index` (`DATETIME`,`RTU_NB`)

Со следующим SQL-оператором:

SELECT * FROM met_value
WHERE rtu_nb=constant
AND mp_nb=constant
AND datetime BETWEEN constant AND constant
ORDER BY mp_nb, datetime
  • Было бы достаточно удалить индекс met_value_index1 и создать его с новымordering RTU_NB, MP_NB, DATETIME?
  • Нужно ли включать RTU_NB в предложение ORDER BY?

Результат: Я попробовал то, что предложил @meriton, и добавил индекс met_value_index2.SELECT завершено через 1,2 секунды, ранее оно завершилось через 5,06 секунды.Следующее относится не к вопросу, а как примечание: после некоторых других попыток я переключил движок с MyISAM на InnoDB - с rtu_nb, mp_nb, datetime в качестве первичного ключа - и оператор завершился через 0,13 секунды!

Ответы [ 3 ]

1 голос
/ 22 декабря 2011

Я не думаю, что он будет использовать какой-либо индекс для ORDER BY.Но вы должны посмотреть на план выполнения .Или здесь .

1 голос
/ 23 декабря 2011

Я не получил ваш запрос.Если строка должна соответствовать mp_np = constant, чтобы быть возвращенной, все возвращенные строки будут иметь одинаковые mp_nb, поэтому включение mp_nb в предложение order by не имеет никакого эффекта.Я рекомендую вам использовать семантически эквивалентный оператор:

SELECT * FROM met_value
WHERE rtu_nb=constant
AND mp_nb=constant
AND datetime BETWEEN constant AND constant
ORDER BY datetime

, чтобы избежать ненужной путаницы в оптимизаторе запросов.

Теперь к вашему вопросу: база данных может реализовать предложение по предложению без сортировки, если онознает, что базовый доступ вернет строки в правильном порядке.В случае индексов это означает, что индекс может помочь с сортировкой, если строки, соответствующие предложению where, появляются в индексе в порядке, запрошенном предложением order by.

Это именно тот случай, поэтомубаза данных может на самом деле выполнить сканирование диапазона индекса по met_value_index1 для строк, где rtu_nb=constant AND datetime BETWEEN constant AND constant, а затем проверить, является ли mp_nb=constant для каждой из этих строк, но это будет означать проверку гораздо большего количества строк, чем необходимо, если mp_nb=constant имеетвысокая селективностьИными словами, индекс наиболее полезен, если совпадающие строки являются непрерывными в индексе, поскольку это означает, что сканирование диапазона индекса будет касаться только тех строк, которые действительно должны быть возвращены.

Следовательно, следующий индекс будет более полезным для этого запроса:

UNIQUE KEY `met_value_index2` (`RTU_NB`,`MP_NB`, `DATETIME`),

, поскольку все совпадающие строки будут находиться рядом друг с другом в индексе, а строки появляются в индексе вЗакажите order by запросы пункта.Я не могу сказать, достаточно ли умен оптимизатор запросов, чтобы получить это, поэтому вам следует проверить план выполнения.

0 голосов
/ 22 декабря 2011

Порядок полей, отображаемых в предложении WHERE, должен соответствовать порядку в индексе. Таким образом, для текущего запроса вам нужен один индекс с полями в следующем порядке: rtu_nb, mp_nb, datetime.

...