Я пытаюсь выяснить, что быстрее: предложение типа «WHERE IN (SELECT 1 FROM MyTable)» или предложение типа «WHERE EXISTS (SELECT 1 FROM MyTable)».

Воспользуемся запросом из документации SqlServer:

SELECT * FROM Orders 
WHERE ShipRegion = 'WA' AND EXISTS (
    SELECT EmployeeID FROM Employees AS Emp 
    WHERE Emp.EmployeeID = Orders.EmployeeID)

Или же

SELECT * FROM Order
WHERE ShipRegion = 'WA' AND EmployeeID IN (
    SELECT EmployeeID FROM Employees AS Emp 
    WHERE Emp.EmployeeID = Orders.EmployeeID)

Я хотел бы знать ответ, если он у кого-то есть, но мне действительно хотелось бы знать, как проверить его на себе в SqlServer 2005. (Я новичок в SqlServer.)

Благодарность!

0
EoRaptor013 2 Июл 2009 в 03:33

4 ответа

Лучший ответ

Чтобы убедиться в этом, вы можете: сравнить реальные затраты на выполнение, запустить

SET STATISTICS IO ON
SET STATISTICS TIME ON

Затем запустите оба запроса

Также сравните планы выполнения, выделите оба запроса и нажмите Ctrl + L, и вы увидите планы. Скорее всего, вы увидите идентичные планы.

2
A-K 2 Июл 2009 в 02:03

Подзапрос sql, хотя и идентичен, не даст вам ответа, который вы ищете, поскольку он связан и может быть изменен на JOIN.

В общем, EXISTS () должен быть быстрее, поскольку он дает результат без необходимости искать какие-либо отношения после того, как он нашел первую строку, тогда как IN () все еще должен найти последующие строки, пока он не завершится.

Следовательно

SELECT * FROM Orders 
WHERE ShipRegion = 'WA' AND EXISTS (
    SELECT 'x' FROM Employees AS Emp 
    WHERE Emp.EmployeeID = 42)

Должен закончить раньше

SELECT * FROM Order
WHERE ShipRegion = 'WA' AND EmployeeID IN (
    SELECT EmployeeID FROM Employees AS Emp 
    WHERE Emp.EmployeeID = 42)
1
John GriffithsJohn Griffiths 2 Июл 2009 в 02:26

Вы также можете удалить предложение WHERE в случае IN:

SELECT * FROM Orders
WHERE ShipRegion = 'WA' AND EmployeeID IN (SELECT EmployeeID FROM Employees)

Оптимизатор запросов должен иметь возможность генерировать идентичный план выполнения для обоих запросов. Я бы выбрал более читаемый.

1
mmx 1 Июл 2009 в 23:40

Использование INNER JOIN будет быстрее, чем подзапрос:

SELECT * 
  FROM Order o
 INNER JOIN Employees e ON o.EmployeeID = e.EmployeeID
 WHERE ShipRegion = 'WA'

Или с конкретными критериями:

 SELECT * 
  FROM Order o
 INNER JOIN Employees e ON o.EmployeeID = e.EmployeeID
 WHERE ShipRegion = 'WA'
   AND e.EmployeeID = 42
3
jn29098 2 Июл 2009 в 02:38