КОГДА запускать запрос занимает слишком много времени, хотя он возвращает небольшое количество или записей? - PullRequest
0 голосов
/ 06 августа 2020

Я работаю на SQL сервере 2012. Я сталкиваюсь с проблемой при выполнении запроса ниже. Требуется 9 минут, чтобы вернуть только 900 строк.

SELECT fmat.Value as PLID,c.CodeTypeId,
COUNT(DISTINCT tr.PartID) [#partsHasCodes]
into #partsHasCodes
FROM Parts.TradeCodes tr WITH(NOLOCK) 
INNER JOIN Parts.Nop_Part pt WITH(NOLOCK) ON pt.PartID = tr.PartID
INNER JOIN Parts.Nop_PartsFamilyAttribute fmat WITH(NOLOCK) ON  fmat.PartFamilyID=pt.PartsFamilyID AND fmat.[Key]=20281007
inner join #TempPlAndCodeType c on (c.CodeTypeId=tr.CodeTypeID)
GROUP BY fmat.Value,c.CodeTypeId

Что я пробовал:

это выполнение plan:

https://www.brentozar.com/pastetheplan/?id=HJXDEp_bv

Добавить индекс кластера в #TempPlAndCodeType:

create clustered index idx on #TempPlAndCodeType (CodeTypeId)

, но по-прежнему занимает слишком много времени

, так что я делаю, чтобы улучшить запрос, по крайней мере, минимизировать время ?

1 Ответ

1 голос
/ 06 августа 2020

Перед применением фильтрации вы читаете много строк. Вы можете изменить порядок joins и использовать force the join order по подсказке, но лучше будет упростить запрос. Не могли бы вы попробовать это?

CREATE TABLE #Buffer
(
    [PartID] BIGINT PRIMARY KEY-- or the type it is
)

INSERT INTO #Buffer ([PartID])
SELECT DISTINCT pt.PartID
FROM Parts.Nop_Part pt WITH(NOLOCK) 
INNER JOIN Parts.Nop_PartsFamilyAttribute fmat WITH(NOLOCK) 
    ON  fmat.PartFamilyID=pt.PartsFamilyID 
    AND fmat.[Key]=20281007;

SELECT fmat.Value as PLID
      ,c.CodeTypeId
      ,COUNT(DISTINCT tr.PartID) [#partsHasCodes]
into #partsHasCodes
FROM Parts.TradeCodes tr WITH(NOLOCK) 
INNER JOIN #Buffer pt WITH(NOLOCK) 
    ON pt.PartID = tr.PartID
inner join #TempPlAndCodeType c 
    on c.CodeTypeId = tr.CodeTypeID
GROUP BY fmat.Value
        ,c.CodeTypeId; 

Идея состоит в том, чтобы сначала отфильтровать по таблице Parts.Nop_PartsFamilyAttribute, чтобы получить необходимые partid s. Затем, чтобы извлечь данные. На скриншоте ниже видно, что вы начинаете с чтения 50 миллионов строк и выделяете ~ 700 МБ памяти. Тогда после фильтрации по таблице Parts.Nop_PartsFamilyAttribute получаем всего 14 миллионов.

введите описание изображения здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...