Добавление предложения ORDER BY в запрос MySQL приводит к его возврату через ~ 30 секунд, вместо ~ 0.5 - PullRequest
2 голосов
/ 15 января 2009

Таким образом, у меня есть относительно быстрый запрос ~ 0,5 секунды, но когда я добавляю предложение ORDER BY, он увеличивается почти до 30 секунд.

Исходный запрос: (возвращается через ~ 0,5 секунды)

SELECT table1.*,table2.* FROM table1 LEFT OUTER JOIN table2 ON table1.column2=table2.column3 WHERE table1.column1='value' LIMIT 4

Запрос с ORDER BY: (возвращается через ~ 30 секунд)

SELECT table1.*,table2.* FROM table1 LEFT OUTER JOIN table2 ON table1.column2=table2.column3 WHERE table1.column1='value' ORDER BY table1.column4 DESC LIMIT 4

Примечание. Я добавил индекс к столбцу, который используется ORDER BY, и он ничего не изменил.

Любые идеи относительно того, что будет причиной этого?

Ответы [ 6 ]

10 голосов
/ 15 января 2009

Это занимает больше времени, поскольку запрос не может просто выбрать первые 4 найденных элемента. Он должен упорядочить весь список, а затем выбрать из них топ-4.

Исправьте это, добавив индекс, который включает table1 {column4, ...}. Если вам нужны только несколько столбцов из таблицы 1 (и они узкие), я бы добавил их все в индекс ( охватывающий индекс ).

При правильной индексации механизм SQL может извлекать только первые четыре столбца, которые вам нужны, а не весь набор.

Если у вас есть индексирование и это не помогает, выполните запрос с помощью EXPLAIN , чтобы увидеть, как выглядит план выполнения (хороший совет, @IronGoofy):

EXPLAIN 
  SELECT table1.*,table2.* 
  FROM table1 
  LEFT OUTER JOIN table2 ON table1.column2=table2.column3 
  WHERE table1.column1='value' ORDER BY table1.column4 DESC LIMIT 4
2 голосов
/ 15 января 2009

Согласны с объяснением Майкла, + 1.

Что касается индекса, не имеющего значения, взгляните на план выполнения (не знаете, как это сделать в MySQL - может быть, кто-то может отредактировать это?). Опять же, я согласен с Майклом в том, что это должно ускорить процесс (если column4 "избирательно").

@ kogus: получение полного набора результатов для клиента не совпадает с упорядочением набора результатов, упорядочение должно осуществляться на сервере без необходимости передачи всех результатов по сети

1 голос
/ 15 января 2009

Индексируется ли table1.column1? Если да, то оптимизатор запросов будет использовать этот индекс для выбора начального набора строк из таблицы1, поскольку в худшем случае это сканирование диапазона индекса (очень быстрое).

Если этот запрос часто выполняется, вы можете получить желаемую производительность с помощью индексации (column1, column4). Я не очень хорошо знаю MySQL, но с Oracle вы могли бы еще больше повысить производительность за счет индексирования (column1, column4, column2), что заставило бы оптимизатор выполнять всю свою работу из индекса, а не касаться данных таблицы вообще.

Однако , добавление индексов является компромиссом: оно увеличит время, затрачиваемое на каждую вставку (или обновление индексированных столбцов), увеличит вашу базу данных и может привести к общему замедлению, так как нехватка ресурсов памяти (т. е. буферный кеш) присваивается новому индексу.

0 голосов
/ 15 января 2009

Согласовано с индексом, упомянутым Михаилом .

Кроме того, в MySQL вы можете многое узнать о производительности вашего запроса, изучив результаты добавления EXPLAIN к вашему запросу, например,

EXPLAIN SELECT * FROM foo_tbl WHERE foobar = 'foo'

поможет вам лучше проектировать ваши запросы и соответствующим образом индексировать. Читайте о Синтаксис EXPLAIN и Оптимизация запросов с помощью EXPLAIN .

0 голосов
/ 15 января 2009

Попробуйте запустить объясните :

EXPLAIN SELECT table1.*,table2.* FROM table1 LEFT OUTER JOIN table2 ON table1.column2=table2.column3 WHERE table1.column1='value' ORDER BY table1.column4 DESC LIMIT 4

Это, вероятно, скажет вам, что MySQL выполняет сортировку файлов. Можете ли вы добавить индекс (column1, column4)?

Можешь рассказать что-нибудь о своей модели? Какие индексы вы используете? Можете показать некоторые объяснения? Какие типы используются для полей?

0 голосов
/ 15 января 2009

Как вы выполняете запрос?

Для некоторых инструментов характерно извлекать только первые 100 или около того записей и при необходимости извлекать больше.

Добавление ORDER BY заставляет инструмент извлекать ВЕСЬ набор данных.

Если вы находитесь в браузере MySql, попробуйте запустить без ORDER BY, а затем используйте CTRL-END для прокрутки к нижней части таблицы данных. Сколько времени это займет?

...