MySQL QueryOptimizer, кажется, случайно использует индекс (или нет)

Я только что обнаружил следующее поведение MySQL с использованием движка InnoDB. Есть ли способ объяснить значительную разницу во времени выполнения?

Первый запрос:

   SELECT ask FROM history_time  WHERE ask> 1.5790 AND timestamp BETWEEN 1207000800290 AND        1207690900290 

Время выполнения: 0,715 сек.

   EXPLAIN: '1', 'SIMPLE', 'history_time', 'range', 'PRIMARY,timestamp,ask,ask_2', 'PRIMARY', '8', NULL, '3278190','Using where'

Второй запрос:

SELECT ask FROM history_time  WHERE ask> 1.5790 AND timestamp > 1207000800290

Время выполнения: 0,002 сек.

EXPLAIN: '1', 'SIMPLE', 'history_time', 'range', 'PRIMARY,timestamp,ask,ask_2', 'ask', '4', NULL, '5850604', 'Using where; Using index'

Третий запрос:

SELECT ask FROM history_time  WHERE ask> 1.5790 AND timestamp < 1207690900290

Время выполнения: 0,651 сек.

EXPLAIN: '1', 'SIMPLE', 'history_time', 'range', 'PRIMARY,timestamp,ask,ask_2', 'PRIMARY', '8', NULL, '3278190', 'Using where'

EXPLAIN говорит мне, что только второй запрос использует Index. Моя таблица содержит 83 млн. строки, первичный ключ — это временная метка. У меня также есть индекс (спросить, отметка времени) и один по запросу (который является избыточным и предназначен только для целей тестирования). Почему MySQL использует индекс только для второго запроса?


person user871784    schedule 12.01.2012    source источник
comment
можете ли вы добавить объяснения для каждого запроса, пожалуйста, и, пожалуйста, время ваших запросов sql, используя SQL_NO_CACHE : SELECT SQL_NO_CACHE ask FROM history_time WHERE ask> 1.5790 AND timestamp > 1207000800290   -  person frail    schedule 12.01.2012
comment
спасибо, я только что добавил объяснение - синхронизация выполняется без использования кеша   -  person user871784    schedule 12.01.2012


Ответы (2)


Ваш ответ заключается в следующем: Метод доступа к диапазону для индексов, состоящих из нескольких частей

Изменить. Также вам лучше проверить это: индекс диапазона mysql. есть вероятность, что оптимизатор решит, что будет быстрее использовать полное сканирование, чем индексирование.

person frail    schedule 12.01.2012
comment
Спасибо за вашу помощь! Есть ли способ оптимизировать это? - person user871784; 12.01.2012
comment
это зависит от кардинальности столбца запроса. если вы будете запрашивать определенное время, а ваши синхронизированные данные меньше, чем запрос кардинальности, я бы предложил индекс по метке времени; в противном случае это было бы пустой тратой ресурсов и пространства. - person frail; 12.01.2012

Ваш запрос специально ранжируется по отметке времени в качестве первичного ключа, а также по индексу Ask через ваш комментарий (ask, timestamp). Поменяйте местами... вам нужна меньшая степень детализации в первой позиции... (метка времени, запрос)... если только вы не запрашиваете очень конкретное значение запроса или диапазон значений запроса. Подумайте об этом так.

Если у вас есть 83 миллиона строк, и вы запрашиваете что-то, что произошло в пределах временных рамок X и Y, отметка времени является вашей основой... зачем рассматривать что-то меньшее или большее, чем рассматриваемый диапазон. Теперь, если вы добавите «ask > someValue», оптимизатор может запутаться. Угадайте... есть ли меньше значений, которые превышают значение Ask, или меньше значений на основе предоставленного диапазона меток времени. Если бы у вас был включен индекс (метка времени, запрос), он мог бы использовать его лучше. В пределах предоставленного диапазона укажите только ask > SomeValue.

Если оптимизатор использовал текущий индекс Ask, он в основном просматривает все записи, которые превышают предоставленное значение... затем в каждой из них перескакивает на те, которые находятся в диапазоне отметок времени.

Теперь поменяйте критерии. Если бы вы искали конкретное значение или диапазон «аск», то ваш текущий индекс был бы идеальным. Он сосредоточится только на этом диапазоне.

person DRapp    schedule 12.01.2012
comment
Как поможет индекс (timestamp, ask)? Запрос использует условия диапазона для обоих столбцов. - person ypercubeᵀᴹ; 29.01.2012
comment
@ypercube, я думаю, я смотрел на первую запись с промежуточной базой, но широко открытые критерии проигрыша, не зная больше статистики о значениях диапазона запросов или о том, чего они на самом деле пытаются достичь в результатах, сложны. Тем не менее, используя отметку времени в первой позиции и между ними, если можно было бы сначала оптимизировать определенный диапазон, а затем захватывать только те записи, которые больше, чем значение запроса, по сравнению со всеми значениями запроса, которые могут быть от лет до текущего. Жесткий вызов в противном случае. - person DRapp; 29.01.2012