2015-10-22 3 views
3

Я использую PostgreSQL 9.3 и имеют следующие таблицы (упрощенно показаны только соответствующие поля):Производительность: LEFT JOIN против подзапрос

SITES: 
id 
name 
... 

DEVICES: 
id 
site_id 
mac_address UNIQUE 
... 

Учитывая наличие mac_address конкретного устройства, и я хочу, чтобы получить детали связанных site. У меня есть следующие два запрос:

Использование LEFT JOIN:

SELECT s.* FROM sites s 
LEFT JOIN devices d ON s.id = d.site_id 
WHERE d.mac_address = '00:00:00:00:00:00'; 

Использование подзапроса:

SELECT s.* FROM sites s 
WHERE s.id IN (SELECT d.site_id FROM devices d WHERE d.mac_address = '00:00:00:00:00:00'); 

Какой из этих двух запросов будет иметь лучшую производительность по сравнению с бесконечно растущей базой данных? Я всегда склонялся к опции LEFT JOIN, но было бы интересно узнать, как производительность обеих ставок на большом наборе данных.

+1

Возьмите 'EXPLAIN' и проверьте его сами. – zerkms

+1

Или еще лучше: используйте 'explain analysis'. Плюс: если у вас есть несколько строк в 'устройствах 'с тем же mac_address, то эти два утверждения не делают то же самое. –

+0

Я думаю, что они даже генерируют разные результаты, поэтому они несравнимы. – Caramiriel

ответ

5

Как правило, это не имеет никакого значения, поскольку они должны приводить к одному и тому же плану запроса. По крайней мере, подзапрос EXISTS будет; IN не всегда так разумно оптимизирован.

Для подзапроса, а не для использования IN (...), вы обычно должны предпочесть EXISTS (...).

SELECT s.* 
FROM sites s 
WHERE EXISTS (
    SELECT 1 
    FROM devices d 
    WHERE d.mac_address = '00:00:00:00:00:00' 
    AND d.site_id = s.id 
); 
+0

Поскольку 'mac_address' уникален, я не думаю, что' IN' и 'EXISTS' будут иметь большое значение. –

+1

Я никогда раньше не использовал 'EXISTS', похоже, что это может быть полезно в этой ситуации. Из документации: «Подзапрос, как правило, будет выполняться достаточно далеко, чтобы определить, возвращается ли хотя бы одна строка, а не весь путь к завершению». Говорит мне, что «EXISTS» остановится, как только будет сопоставлен «mac_address», где «IN» продолжит работу. Может быть, разница в сотнях тысяч строк. –

Смежные вопросы