Упорядочить по выполнению предложения в SQL
Этот вопрос не касается порядка казней. Речь идет только о порядке.
В стандартном исполнении это:
FROM WHERE GROUP BY HAVING SELECT ORDER BY TOPEDIT: This question has been more or less the issue of "Does SQL Server apply short circuit evaluation when executing ORDER BY expressions?" The answer is SOMETIMES! I just haven't found a reasonable reason as to why. See Edit #4.
Теперь предположим, что у меня есть такое утверждение:
DECLARE @dt18YearsAgo AS DATETIME = DATEADD(YEAR,-18,GETDATE());
SELECT
Customers.Name
FROM
Customers
WHERE
Customers.DateOfBirth > @dt18YearsAgo
ORDER BY
Contacts.LastName ASC, --STATEMENT1
Contacts.FirstName ASC, --STATEMENT2
(
SELECT
MAX(PurchaseDateTime)
FROM
Purchases
WHERE
Purchases.CustomerID = Customers.CustomerID
) DESC --STATEMENT3
Это не реальное утверждение, которое я пытаюсь выполнить, а всего лишь пример. Существует три оператора ORDER BY. Третье утверждение используется только в тех редких случаях, когда фамилия и имя совпадают.
Если нет повторяющихся фамилий, SQL Server не выполняет операторы ORDER BY # 2 и # 3? И, логически, если нет повторяющихся фамилии и имени, SQL Server note выполняет оператор # 3.
Это действительно для оптимизации. Чтение из таблицы покупок должно быть только последним средством. В случае с моим приложением было бы неэффективно читать все «PurchaseDateTime». от & quot; Закупки & quot; группировка по "CustomerID".
Пожалуйста, сохраняйте ответ, связанный с моим вопросом, а не предложение, например, создание индекса для CustomerID, PurchaseDateTime в разделе «Покупки». Вопрос в том, пропускает ли SQL Server ненужные операторы ORDER BY?
Изменить: Очевидно, SQL Server всегда будет выполнять каждый оператор, пока есть одна строка. Даже с одной строкой это даст вам ошибку деления на ноль:
DECLARE @dt18YearsAgo AS DATETIME = DATEADD(YEAR,-18,GETDATE());
SELECT
Customers.Name
FROM
Customers
WHERE
Customers.DateOfBirth > @dt18YearsAgo
ORDER BY
Contacts.LastName ASC, --STATEMENT1
Contacts.FirstName ASC, --STATEMENT2
1/(Contacts.ContactID - Contacts.ContactID) --STATEMENT3
Edit2: По-видимому, это не дает деления на ноль:
DECLARE @dt18YearsAgo AS DATETIME = DATEADD(YEAR,-18,GETDATE());
SELECT
Customers.Name
FROM
Customers
WHERE
Customers.DateOfBirth > @dt18YearsAgo
ORDER BY
Contacts.LastName ASC, --STATEMENT1
Contacts.FirstName ASC, --STATEMENT2
CASE WHEN 1=0
THEN Contacts.ContactID
ELSE 1/(Contacts.ContactID - Contacts.ContactID)
END --STATEMENT3
Ну, первоначальный ответ на мой вопрос - ДА, он выполняется, но приятно то, что я могу прекратить выполнение с надлежащим СЛУЧАЙ КОГДА
Редактировать 3: Мы можем остановить выполнение оператора ORDER BY с надлежащим CASE WHEN. Хитрость, я думаю, заключается в том, чтобы понять, как правильно его использовать CASE WHEN даст мне то, что я хочу, - выполнение короткого замыкания в операторе ORDER BY. Я сравнил План выполнения в SSMS и, в зависимости от оператора CASE WHEN, таблица Закупки не сканируется даже ДАЛЕЕ, КАК это ясно видимый оператор SELECT / FROM:
DECLARE @dt18YearsAgo AS DATETIME = DATEADD(YEAR,-18,GETDATE());
SELECT
Customers.Name
FROM
Customers
WHERE
Customers.DateOfBirth > @dt18YearsAgo
ORDER BY
Contacts.LastName ASC, --STATEMENT1
Contacts.FirstName ASC, --STATEMENT2
CASE WHEN 1=0
THEN
(
SELECT
MAX(PurchaseDateTime)
FROM
Purchases
WHERE
Purchases.CustomerID = Customers.CustomerID
)
ELSE Customers.DateOfBirth
END DESC
Изменить 4: Теперь я полностью запутался. Вот пример @Lieven
WITH Test (name, ID) AS
(SELECT 'Lieven1', 1 UNION ALL SELECT 'Lieven2', 2)
SELECT * FROM Test ORDER BY name, 1/ (ID - ID)
Это не дает деления на ноль, что означает, что SQL Server фактически выполняет оценку короткого замыкания в НЕКОТОРЫХ таблицах, особенно тех, которые созданы с помощью команды WITH.
Попытка это с переменной TABLE:
DECLARE @Test TABLE
(
NAME nvarchar(30),
ID int
);
INSERT INTO @Test (Name,ID) VALUES('Lieven1',1);
INSERT INTO @Test (Name,ID) VALUES('Lieven2',2);
SELECT * FROM @Test ORDER BY name, 1/ (ID - ID)
даст ошибку деления на ноль.