Является ли предложение HAVING избыточным?

Следующие два запроса дают тот же результат:

select country, count(organization) as N
from ismember
group by country
having N > 50;

select * from (
  select country, count(organization) as N
  from ismember
  group by country) x
where N > 50;

Можно ли заменить каждое предложение HAVING суб-запросом и предложением WHERE следующим образом? Или существуют ситуации, когда предложение HAVING абсолютно необходимо/более мощно/более эффективно/независимо?

Ответ 1

Здесь задано два вопроса: ответ на первый из них да: Полученный результат запроса HAVING -laden идентичен набору результатов того же запроса, который выполняется как подзапрос, украшенное предложением WHERE.

Второй вопрос касается производительности и выразительности - здесь мы активно работаем над реализацией. В MySQL есть тонкая красная линия, где производительность начинает дрейфовать: момент, когда результаты внутреннего запроса больше не сохраняются в памяти. В этом случае MySQL создаст внутреннее представление на диске, а затем использует селектор WHERE. Этого не произойдет, если используется предложение HAVING, дисквалифицированная группа будет удалена из набора результатов.

Это означает, что чем выше избирательность в предложении HAVING, тем больше у него важна значимость: рассмотрим набор результатов из миллиона строк внутреннего запроса, который сокращается на HAVING до 5 строк - очень вероятно, что результирующий набор внутреннего запроса не будет храниться в памяти, но очень вероятно, что конечный набор результатов будет.

Edit

У меня это было одно: запрос выбрал несколько выбросов из очень равномерно распределенной таблицы (количество штук, созданных на физической машине в мастерской в ​​день). Я исследовал из-за высокой IO-нагрузки.

Изменить 2

Пожалуйста, имейте в виду, что кеш запросов не, используемый для подзапросов. ИМХО. Развитие места должно сосредоточиться больше - так что шаблон подзапроса не будет получать прибыль из внутреннего запроса, являющегося кешированным набором результатов.

Ответ 2

В Sql Server 2008 два похожих запроса имеют точно такой же план выполнения:

enter image description here

Я также изучил много запросов, созданных Entity Framework (с SS 2008), и до сих пор я никогда не видел запроса с предложением HAVING. Группировка запросов с условием на агрегированный результат всегда преобразуется в запрос с подзапросом. Я уверен, что команда ADO.Net знает, что они делают...

Ответ 3

Предложение HAVING очень полезно, чтобы избежать дополнительной сложности подзапросов. Однако эти два логически эквивалентны, и каждое предложение HAVING может быть переписано с использованием подзапроса, как у вас.

Если вам интересно, вы можете также написать каждое предложение WHERE в качестве предложения HAVING, если вы готовы максимально использовать GROUP BY.

Ответ 4

IMHO, использование предложения HAVING должно быть эффективным, поскольку в рабочей таблице будет дополнительный проход, который содержит сгруппированные результаты, поверх которых будут выполняться критерии фильтрации, во втором случае.

Ответ 5

Я знаю, что вы изменили его из общего в MySQL, но я хотел бы добавить здесь примечание (может быть полезно). С небольшим изменением я попробовал ваш запрос в SQL Server 2008.

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

Ответ 6

Логически да, результат будет таким же в конце. Но производительность может отличаться. Предложение HAVING может привести к тому, что БД изменит другой план выполнения.

Заметка для ребята выше (не может напрямую комментировать) - план выполнения зависит не только от вашего запроса. Он также может быть скорректирован БД в зависимости от статистики, такой как размер таблицы и т.д. Во время выполнения. Тем не менее для DB2 по крайней мере...