Проблемы с производительностью SQL Server при использовании EXCEPT в запросе - PullRequest
0 голосов
/ 08 февраля 2019

В общем, у меня есть запрос SELECT в сочетании с тремя независимыми запросами SELECT.Я использую в запросе операторы EXCEPT и UNION .При самостоятельном выполнении запросов я получу результаты через 1-2 секунды, но при наличии оператора EXCEPT запрос займет часы.

Структура запроса (в упрощенном виде) выглядит следующим образом:

SELECT DISTINCT FIELD_1, FIELD_2, FIELD_3 FROM MYTABLE

EXCEPT

(
SELECT DISTINCT FIELD_1, FIELD_2, FIELD_3 FROM MYTABLE WHERE XXX

UNION

SELECT DISTINCT FIELD_1, FIELD_2, FIELD_3 FROM MYTABLE WHERE YYY
)

Есть ли способы ускорить весь запрос или это оператор EXCEPT в целом, поэтомумедленно, что следует избегать?

Ответы [ 4 ]

0 голосов
/ 08 февраля 2019

Вы можете сделать это с помощью GROUP BY

SELECT FIELD_1, FIELD_2, FIELD_3 
FROM MYTABLE
GROUP BY FIELD_1, FIELD_2, FIELD_3 
HAVING MAX(CASE WHEN (XXX) OR (YYY) THEN 1 ELSE 0 END) = 0
0 голосов
/ 08 февраля 2019

Я бы использовал NOT EXISTS вместо CTE:

WITH CTE AS (
     <your union query>
)
SELECT mt.*
FROM MYTABLE mt
WHERE NOT EXISTS (SELECT 1 FROM CTE c WHERE c.FIELD_1 = mt.FIELD_1 AND . . . );   
0 голосов
/ 08 февраля 2019

Во-первых, я бы не использовал field to with, лучше использовать Id, потому что он негибкий

Карьер ниже будет иметь гораздо более высокую производительность.

Так я бы поступилит.

SELECT DISTINCT FIELD_1, FIELD_2, FIELD_3 FROM MYTABLE
where Id not in (
SELECT Id FROM MYTABLE WHERE XXX and YYY
)
0 голосов
/ 08 февраля 2019

Иногда полезно упростить задачу для оптимизатора запросов, разбив рабочую нагрузку на несколько этапов.Особенно, если выполнение может занять несколько часов:

-- Step 1
SELECT FIELD_1, FIELD_2, FIELD_3 INTO #Step1 FROM
(
SELECT FIELD_1, FIELD_2, FIELD_3 FROM MYTABLE WHERE XXX    
UNION  
SELECT FIELD_1, FIELD_2, FIELD_3 FROM MYTABLE WHERE YYY
) d

-- Step 2:
SELECT DISTINCT FIELD_1, FIELD_2, FIELD_3 FROM MYTABLE    
EXCEPT    
SELECT FIELD_1, FIELD_2, FIELD_3  FROM #Step1

Обратите внимание, что некоторые пункты DISTINCT удалены


Обновление, версия 3. На основе последнего обновленияOP:

Tab: это та же самая таблица.Первый запрос в основном дает почти всю таблицу, а второй + третий запрос - это подмножества, которые мне нужно извлечь из результатов первого запроса

Я считаю, что весь запрос можно переписать так:

SELECT DISTINCT FIELD_1, FIELD_2, FIELD_3 FROM MYTABLE ext
WHERE NOT EXISTS (

SELECT * FROM (
    SELECT FIELD_1, FIELD_2, FIELD_3 FROM MYTABLE  
    WHERE  ( (XXX) OR (YYY))  -- original filter
)   list 
WHERE
    list.FIELD_1 = ext.FIELD_1
AND list.FIELD_2 = ext.FIELD_2
AND list.FIELD_3 = ext.FIELD_3
) 
...