Я хочу понять следующее.
Предположим, что у меня сложный запрос с, скажем, объединением 5 таблиц в группу по сумме и по порядку.
Оставляя в стороне какие-либо оптимизации самого запроса, например, индексы и т. Д.
Есть ли какое-либо существенное преимущество в производительности LIMIT
? Я предполагаю, что весь запрос (и результаты) должен быть обработан до применения LIMIT, поэтому использование LIMIT для получения подмножества результатов дает ли это какое-либо значительное / заметное улучшение?
mysql
performance
join
Джим
источник
источник
LIMIT
повышают эффективность: Оптимизация запросов LIMITОтветы:
Если вы хотите воспользоваться преимуществами
LIMIT
для повышения производительности, вам нужноLIMIT
передJOIN
Эти принципы могут иметь большое значение, если вы можете их организовать.
Я изучил эти понятия, посмотрев это видео на YouTube (внимательно слушайте через французский акцент)
Я использовал эти концепции, чтобы ответить на очень сложный вопрос StackOverflow о получении 40 лучших статей из некоторых таблиц: 12 мая 2011 г .: извлечение отдельной строки из таблицы соединений .
В своем ответе на этот вопрос (16 мая 2011 г.) я написал следующий запрос и тщательно его протестировал:
Обратите внимание на строку в запросе с
LIMIT
Этот подзапрос скрыт на трех уровнях. Это позволило мне использовать последние 40 статей
LIMIT
. Затем я выполнил необходимые соединения после этого.УРОКИ ВЫУЧЕНЫ
LIMIT
внутри подзапросов не всегда может быть ответом из-за количества индексов, содержимого данных и размера результирующего набора изLIMIT
. Если у вас есть все ваши «утки подряд» (запомните четыре принципа для вашего запроса), вы можете получить удивительно хорошие результаты.LIMIT
, собирая только ключи.источник
(A [LEFT] JOIN B) LIMIT 100
эквивалентно(A LIMIT 100) [LEFT] JOIN (B LIMIT 100)
? Где[LEFT] JOIN
означает внешнее или внутреннее соединение(A LIMIT 100) [LEFT] JOIN B
. Идея состоит в том, чтобы использоватьLIMIT
размер результирующего набора как можно раньше. Я также используюLEFT JOIN
вместо того,INNER JOIN
потомуLEFT JOIN
что сохранит порядок клавиш на левой стороне.(A LEFT JOIN B) GROUP BY A.pk LIMIT 100
обычно могут быть переписаны как(A LIMIT 100) LEFT JOIN B GROUP BY A.pk
(никакого ВНУТРЕННЕГО СОЕДИНЕНИЯ здесь, с внутренними объединениями они не будут эквивалентны.) Пример Роландо как раз такой случай.Когда запрос выполняется, он сначала переводится в план, состоящий из нескольких операторов. Существует два основных типа операторов: блокирующие и неблокирующие. Неблокирующий оператор извлекает строку (или несколько строк) из своего потомка или потомков для каждой строки, запрошенной из него. Оператор блокировки, с другой стороны, должен прочитать и обработать весь набор строк всех своих дочерних элементов, прежде чем он сможет произвести какой-либо вывод.
Сортировка является типичным оператором блокировки. Таким образом, отбор с заказом по не сильно выигрывает от лимита. Тем не менее, есть RDBMS, которые могут использовать алгоритм сортировки, который требует меньше памяти и быстрее, когда предоставляется условие limit. В этом случае достаточно просто сохранить текущие первые n строк и переместить их из памяти при появлении более ранних строк. Это может быть значительным приростом производительности. Однако я не уверен на 100%, что MySQL обладает такой способностью.
В любом случае, даже сортировка по пределу все еще должна обработать весь набор входных строк, прежде чем она сможет создать первую выходную строку. Хотя этот алгоритм, если он реализован, может ускорить сортировку, если остальная часть запроса является самой дорогой частью, общее время выполнения существенно не улучшится из-за предоставленного ограничения.
источник
GROUP BY
потенциально может привести к тому, что план не содержит операторов блокировки.В моем случае я могу сказать Да , даже если я (все еще) не понимаю почему.
Обратите внимание на время: 18 секунд. Тот же запрос с большим ПРЕДЕЛОМ:
Более чем в десять раз быстрее !!!
EXPLAIN дают одинаковый результат для обоих запросов.
LIMIT должен вмешиваться только для ограничения набора результатов (т. Е. Если я выполню LIMIT 4, я получу только первые 4 строки из вышеуказанного набора результатов).
источник
LIMIT
. Ваш первый запрос выполняется за 18 секунд, давая набор результатов. Все данные во втором запросе уже кэшируются в пуле буферов InnoDB из-за первого запроса, поэтому, конечно, второй запрос должен быть быстрее, даже если вы перезапустите mysql, выполните первый запрос, перезапустите mysql и запустите второй запрос, вы получите тот же результат. , Лучший результат дляLIMIT
может быть получен только от следующих действий: 1)LIMIT
доJOIN
, 2) LIMIT в порядке сортировкиASC
илиDESC
.