Влияет ли избыточный предикат where в SQL-запросе на производительность?

#sql

#sql

Вопрос:

Рассмотрим запрос типа:

 select *
from t
where a = 5 and (a = 5 and b = 7)
  

Влияет ли избыточный предикат a = 5 на производительность запроса. Я думаю, что нет, но мне говорят иначе (да, я знаю, что это зависит от СУБД, но просто предположим, что это какая-то корпоративная СУБД, такая как SQL Server, DB2 или Oracle).

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

1. Это первое условие бессмысленно, оно всегда будет истинным и при выполнении второго условия.

2. Я бы посоветовал взглянуть на ваш план выполнения или план объяснения, чтобы увидеть, есть ли различия в том, как работает оптимизатор. Но лично я бы все равно убрал предложение redunant по причинам обслуживания.

3. Единственный способ, которым этот запрос имеет смысл для меня, — это если предложение where имеет вид where a = 5 or (a = 5 and b = 7)

4. @Ozair Kafray: Я не спрашивал, имеет ли смысл запрос. Я спросил, влияет ли это на производительность.

5. @Dustin, скорее всего, это происходит из какого-то динамического SQL или подготовленного оператора. Никто не стал бы вручную кодировать это. Проблема в том, является ли это проблемой, когда она возникает.

Ответ №1:

Обычно ответом было бы «нет», избыточное предложение не влияет на производительность. Конечно, будучи программистом, вы можете использовать доказательства, чтобы доказать это тем или иным способом (в отличие от человека, который будет повторять свои мифы как факт).

Просто откройте выбранную вами базу данных, введите свой запрос с предложением redundant или без него, затем запросите у вашей базы данных explain оба запроса.

Например, в среде SQL Server Management Studio (MS SQL Server) откройте окно запроса, введите свой запрос, а затем щелкните правой кнопкой мыши и выберите «Отобразить предполагаемый план выполнения» (или вы можете выбрать опцию для отображения фактического плана после выполнения запроса).

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

1. 1, причина, по которой это не влияет на производительность, заключается в том, что ваш администратор базы данных выполняет / должен выполнять оценку короткого замыкания предложения where (см.: en.wikipedia.org/wiki/Short-circuit_evaluation ) и прекратит тестирование, как только результатом будет определенное true или false

2. @Johan: Как здесь помогает короткое замыкание? Наивное короткое замыкание на a == 5 amp;amp; a == 5 amp;amp; b == 7 для некоторой строки, где a == 5 значение true, будет оценивать истинность a == 5 дважды.

3. @Fred, прочитай ссылку и возвращайся, когда поймешь , что short circuit evaluation такое. подсказка это не о том, чтобы делать что-то дважды

4. @Johan: Не надо меня опекать. Вычисление с коротким замыканием останавливает вычисление логического выражения с несколькими предикатами, как только это возможно (поэтому p1 amp;amp; p2 не вычисляет, p2 если p1 это false, и p1 || p2 не вычисляет, p2 если p1 это true). Вернитесь, когда вы разберетесь в вычислении короткого замыкания.

5. @Fred, и вот как это ускоряет работу. Второй тест никогда не выполняется. И если это постоянное выражение, оптимизатор запросов удалит его, прежде чем преобразовать запрос в байтовый код (или что-то еще, что использует исполнитель запросов)

Ответ №2:

Я хотел бы процитировать следующее из Закона дырявых абстракций Джоэла Спольски

Язык SQL предназначен для абстрагирования процедурных шагов, необходимых для запроса к базе данных, вместо этого позволяя вам просто определить, что вы хотите, и позволить базе данных определить процедурные шаги для запроса к этому. Но в некоторых случаях определенные SQL-запросы выполняются в тысячи раз медленнее, чем другие логически эквивалентные запросы. Известным примером этого является то, что некоторые SQL-серверы работают значительно быстрее, если вы укажете «где a = b и b = c и a = c», чем если бы вы указали только «где a = b и b = c», даже если результирующий набор тот же.Предполагается, что вам не нужно заботиться о процедуре, только о спецификации. Но иногда абстракция протекает и приводит к ужасной производительности, и вам приходится запускать анализатор плана запроса и изучать, что он сделал неправильно, и выяснять, как ускорить выполнение вашего запроса.