Я только что обнаружил следующее поведение 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 использует индекс только для второго запроса?
Ответ 2 · DRapp
Ваш запрос специально ранжируется по отметке времени в качестве первичного ключа, а также по индексу Ask через ваш комментарий (ask, timestamp). Поменяйте местами... вам нужна меньшая степень детализации в первой позиции... (метка времени, запрос)... если только вы не запрашиваете очень конкретное значение запроса или диапазон значений запроса. Подумайте об этом так.
Если у вас есть 83 миллиона строк, и вы запрашиваете что-то, что произошло в пределах временных рамок X и Y, отметка времени является вашей основой... зачем рассматривать что-то меньшее или большее, чем рассматриваемый диапазон. Теперь, если вы добавите "ask > someValue", оптимизатор может запутаться. Угадайте... есть ли меньше значений, которые превышают значение Ask, или меньше значений на основе предоставленного диапазона меток времени. Если бы у вас был включен индекс (метка времени, запрос), он мог бы использовать его лучше. В пределах предоставленного диапазона укажите только ask > SomeValue.
Если оптимизатор использовал текущий индекс Ask, он в основном просматривает все записи, которые превышают предоставленное значение... затем в каждой из них перескакивает на те, которые находятся в диапазоне отметок времени.
Теперь поменяйте критерии. Если бы вы искали конкретное значение или диапазон "аск", то ваш текущий индекс был бы идеальным. Он сосредоточится только на этом диапазоне.