Как определить, что эффективнее: DISTINCT или WHERE EXISTS?

Например, у меня есть 3 таблицы: user, group и permission, и между ними две связи many2many: user_groups и group_permissions.

Мне нужно выбрать все разрешения данного пользователя без повторов. Каждый раз, когда я сталкиваюсь с подобной проблемой, я не могу определить, какой вариант запроса лучше:

SELECT permisson_id FROM group_permission WHERE EXISTS(
    SELECT 1 FROM user_groups 
        WHERE user_groups.user_id = 42 
          AND user_groups.group_id = group_permission.group_id
)

SELECT DISTINCT permisson_id FROM group_permission
    INNER JOIN user_groups ON user_groups.user_id = 42 
           AND user_groups.group_id = group_permission.group_id 

У меня достаточно опыта, чтобы делать выводы на основе объяснения. В первом запросе есть подзапрос, но мой опыт показал, что первый запрос быстрее. Возможно, из-за большого количества отфильтрованных разрешений в результате.

Что бы вы сделали в такой ситуации? Почему? Спасибо!


person defuz    schedule 30.08.2012    source источник
comment
вы проверили план explain для них обоих?   -  person Taryn    schedule 30.08.2012
comment
У меня достаточно опыта, чтобы делать выводы на основе объяснения. В первом запросе есть подзапрос, но мой опыт показал, что первый запрос быстрее. Возможно, из-за большого количества permissions подлежащих фильтрации.   -  person defuz    schedule 30.08.2012
comment
Вторые имеют наибольшую производительность. Подзапрос нет быстрый.   -  person Ascension    schedule 30.08.2012
comment
@Ascension yes следует избегать подзапросов; однако EXISTS предписывает серверу прекратить поиск после того, как он найдет первое совпадение, что делает его очень быстрым условием WHERE.   -  person Chris Trahey    schedule 30.08.2012


Ответы (1)


Используйте EXISTS вместо DISTINCT

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

в вашем случае может быть много дублированных данных, поэтому существующие должны быть быстрее.

по http://my.safaribooksonline.com/book/-/9780072229813/high-performance-sql-tuning/ch16lev1sec10

person DadViegas    schedule 30.08.2012
comment
Exists также возвращает результат после нахождения первой строки, так что вы экономите не только на сортировке; также сканирование. - person Chris Trahey; 30.08.2012