Наличие предложения против подзапроса

Я мог бы написать запрос, используя агрегатную функцию, двумя способами:

select team, count(min) as min_count
from table
group by team
having count(min) > 500

or

select * 
from (
    select team, count(min) as min_count
    from table
    group by team
) as A
where A.min_count > 500

Есть ли какие-либо преимущества в производительности для любого из подходов или они функционально одинаковы?


person ferics2    schedule 17.10.2012    source источник
comment
Самое главное: идентичны ли они семантически?   -  person usr    schedule 18.10.2012
comment
Вы тестировали их или просматривали план объяснения?   -  person Taryn    schedule 18.10.2012
comment
Можете ли вы показать план выполнения запроса?   -  person Tim Schmelter    schedule 18.10.2012
comment
Это вопрос, на который необходимо ответить с точки зрения общих принципов. Измерение одного случая - это не то, о чем здесь спрашивают. Это ничего не доказывает о других случаях.   -  person usr    schedule 18.10.2012
comment
@TimSchmelter Я не могу здесь ответить на конкретный запрос из-за информации. Но спасибо за предложение. Я буду смотреть в него.   -  person ferics2    schedule 18.10.2012
comment
Вам нужно использовать псевдоним count(min) во втором запросе, иначе where count > 500 недействителен. Соответствующий вопрос здесь. Вас также может заинтересовать ИМЕТЬ грубую ошибку Время или желание, чтобы вы были ГДЕ   -  person Martin Smith    schedule 18.10.2012
comment
@MartinSmith: ему также нужен псевдоним для подзапроса, по крайней мере, в SQL-Server. Поэтому я предполагаю, что это разные dbms.   -  person Tim Schmelter    schedule 18.10.2012
comment
@TimSchmelter - В Oracle IIRC вы этого не делаете, и они не указали СУБД.   -  person Martin Smith    schedule 18.10.2012
comment
@MartinSmith, я знаю об обоих. Это не точный запрос, а просто быстро написанный. Я ищу здесь не проверки синтаксиса, а ответ на вопрос о том, как выполняются запросы.   -  person ferics2    schedule 18.10.2012
comment
Похоже, вы упустили некоторую важную информацию, необходимую для вопросов о производительности. О какой конкретно СУБД вы спрашиваете? Потому что все сводится к просмотру реализации в этой СУБД.   -  person Martin Smith    schedule 18.10.2012


Ответы (1)


Две версии функционально одинаковы. Что ж, второе синтаксически неверно, но я предполагаю, что вы имеете в виду:

select * 
from (
    select team, count(min) as count
    from table
    group by team
) t
where count > 500

(Вам нужен псевдоним для расчета, а несколько ведущих баз данных требуют псевдоним для подзапроса в предложении FROM.)

Функциональная эквивалентность не означает, что они обязательно оптимизированы одинаково. Часто существует несколько способов написать запрос, которые функционально эквивалентны. Однако конкретный движок/оптимизатор базы данных может выбирать (и часто выбирает) разные пути оптимизации.

В этом случае запрос настолько прост, что трудно придумать несколько путей оптимизации. Для обеих версий движок в основном должен агрегировать запрос, а затем проверять второй столбец для фильтра. Я лично не вижу много вариаций на эту тему. Любой приличный механизм SQL должен использовать индексы, если это необходимо, либо в обоих случаях, либо ни в одном из них.

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

person Gordon Linoff    schedule 17.10.2012