ОГРАНИЧЕНИЕ 0,5 замедляет выполнение запроса в 350 раз

#mysql #database

#mysql #База данных

Вопрос:

Следующий запрос MySQL завершается менее чем за 0,02 секунды:

  SELECT
    *
 FROM
    `Table1`
 WHERE
    `col1`     = '43532' AND
    `col2`     = 'N'
 ORDER BY col3 DESC 
 

Однако, если я добавлю LIMIT 0, 5 в конце, он завершится более чем за 7 секунд:

  SELECT
    *
 FROM
    `Table1`
 WHERE
    `col1`     = '43532' AND
    `col2`     = 'N'
 ORDER BY col3 DESC 
 LIMIT 0, 5
 

Это происходит даже тогда, когда запрос возвращает пустой результирующий набор.

Почему добавление LIMIT 0, 5 этого простого запроса приводит к замедлению в 350 раз? Мне нужно иметь возможность ограничивать результаты по причинам разбивки на страницы, так как я могу это исправить?

Редактировать:

БЕЗ ОГРАНИЧЕНИЯ, EXPLAIN говорит:

 id  select_type table   type    possible_keys   key     key_len   ref     rows  Extra
1   SIMPLE      Table1  ref     col1,col2       col1    5         const   2441  Using where; Using filesort
 

С ОГРАНИЧЕНИЕМ, EXPLAIN говорит:

 id  select_type table   type    possible_keys   key   key_len   ref   rows  Extra
1   SIMPLE      Table1  index   col1,col2       col3  5         NULL  1050  Using where
 

Комментарии:

1. @ckruse: Пожалуйста, посмотрите мою правку выше.

2. Это может быть полезно, как оптимизировать запросы: databasejournal.com/features/mysql/article.php/1382791 /…

3. Это простое объяснение для обоих запросов? Возможно, ОГРАНИЧЕНИЕ заставляет MySQL использовать другой ключ.

4. Можете ли вы добавить «select SQL_NO_CACHE», чтобы убедиться, что вы получаете точные результаты синхронизации, и «ПОКАЗАТЬ ИНДЕКС ИЗ <имя_таблицы>» тоже может быть хорошим. Не могли бы вы также ОБЪЯСНИТЬ оба запроса?

5. @GolezTrol: пожалуйста, смотрите Новое РЕДАКТИРОВАНИЕ выше для 2 разных ОБЪЯСНЕНИЙ, которые я получаю для каждого запроса (с / без ОГРАНИЧЕНИЯ 0,5).

Ответ №1:

Проблема в том, что ограничение заставляет MySQL сначала упорядочивать запрос, заставляя его упорядочивать весь набор, а затем фильтровать его, не используя индексы.

Существуют директивы, указывающие MySQL, какой индекс использовать, но, возможно, лучше создать комбинированный индекс для col1, col2 и col3. MySQL должен использовать этот индекс для фильтрации и сортировки. Вы должны поэкспериментировать, чтобы увидеть, выполняется ли запрос быстрее, если col3 является первым или последним столбцом в этом индексе.

Ответ №2:

Начало ограничения, запас зависит от вычисления движка БД. Для разбивки на страницы не нажимайте на БД каждые 5 строк, лучше всего было бы перенести 500 записей во внешний интерфейс, а затем обслуживать их с помощью javascript, чтобы каждые следующие 500 записей попадали в БД, что будет приемлемо..

Комментарии:

1. Но почему это делает запрос в 350 раз медленнее, даже для пустого результирующего набора? Похоже, что происходит что-то еще…

2. Сначала он извлекает записи, а затем извлекает необходимые строки и вставляет в temp_table, а затем извлекает нужные строки из temp_table…