Как помочь SQL Server подготовить лучший план? - PullRequest
0 голосов
/ 17 мая 2019

Иногда мой запрос в SQL Server занимает несколько минут, а его повторный запуск занимает всего лишь долю секунды.Я предполагаю, что оптимизатор запросов принял неправильное решение в первый раз, но собранные данные позволили ему добиться большего успеха в следующий раз.Глядя на план запроса, я иногда вижу что-то вроде этого:

estimated vs actual number of rows

Я считаю, что это означает, что оптимизатор неправильно рассчитал количество строк и сделал неверныйрешение, например, как сделать соединение.Как мне «помочь»?Предоставить подсказку?Обновить статистику?Добавить индекс?Перепишите запрос?

Вот еще информация об этой части запроса (как вы видите, уже есть кластеризованный индекс):

Key Lookup node

ОБНОВЛЕНИЕ: вот запрос (сокращенно для краткости):

WITH session_temp AS 
(
    SELECT 
        SESSION_N, SESSION_DATE, SESSION_CREATE_DATE, MASTER_SESSION_N, ROOT_SESSION_N  
    FROM 
        T_SESSION 
    WHERE 
        PATIENT_N = 140945 AND SESSION_ACTIVE_FLAG = 1
)
SELECT  
    S.SESSION_DATE, S.SESSION_CREATE_DATE, 
    SUB_ST.SESSION_N, SUB_ST.XML_VALUE, 'subtemplate' AS SOURCE_TYPE 
FROM 
    session_temp SUB_S 
INNER LOOP JOIN 
    T_SESSION_TEMPLATE SUB_ST ON (SUB_S.SESSION_N = SUB_ST.SESSION_N AND SUB_S.MASTER_SESSION_N IS NOT NULL) 
JOIN
    T_SESSION_TEMPLATE ST ON (SUB_S.ROOT_SESSION_N = ST.SESSION_N) 
JOIN
    session_temp S ON ST.SESSION_N = S.SESSION_N 
JOIN
    T_SESSION_CATEGORY SC ON S.SESSION_N = SC.SESSION_N
WHERE 
    ST.TEMPLATE_N IN (1709, 1686, 1660, 1526, 1474, 1456, 1301, 1258) 
    AND SUB_ST.TEMPLATE_N IN (617) 
    AND SUB_S.MASTER_SESSION_N IS NOT NULL 
    AND S.MASTER_SESSION_N IS NULL 
    AND SC.category_n IN (241, 119, 181, 183, 110)

UNION ALL

SELECT  
    SESSION_DATE, SESSION_CREATE_DATE, ST.SESSION_N, XML_VALUE, 
    'include' AS SOURCE_TYPE
FROM 
    T_SESSION_TEMPLATE ST 
JOIN  
    session_temp S ON ST.SESSION_N = S.SESSION_N
WHERE 
    ST.TEMPLATE_N IN (1709, 1686, 1660, 1526, 1474, 1456, 1301, 1258) 
    AND S.MASTER_SESSION_N IS NULL
ORDER BY 
    SESSION_DATE DESC, SESSION_N DESC 

ОБНОВЛЕНИЕ 2: вот план выполнения: https://www.brentozar.com/pastetheplan/?id=BJL7Bwh3V

1 Ответ

0 голосов
/ 14 июля 2019

Попробуйте добавить XML_VALUE в индекс: IX_T_SESSION_TEMPLATE_SESSION_N. Это должно предотвратить поиск ключа, который вызывает большую часть вашего ввода-вывода.

В вашем плане выполнения вы смотрите на этот раздел:

Partial execution plan

Если навести указатель мыши на оператор поиска ключей (оценка 97%), вы увидите, что ему нужно выполнить поиск по XML_VALUE (более миллиона раз), который можно добавить к сканируемому индексу.

...