T-SQL SELECT * - быстрый, SELECT TOP 50 - медленный - PullRequest
0 голосов
/ 03 июля 2019

(удалено предыдущее сообщение, может быть, его неправильно спросили, попробую еще раз)

    -- 300Ms
    SELECT AppId FROM Application ap
    LEFT OUTER JOIN MissingThings mt on mt.AppId = ap.AppId
    WHERE mt.AppId is NULL
    ORDER BY mt.Id

-- 1.5s
SELECT TOP 50 FROM (TheSame)

    -- 100Ms
    SELECT TOP 50 AppId FROM Application ap
    LEFT OUTER JOIN MissingThings mt on mt.AppId = ap.AppId
    --WHERE mt.AppId is NULL
    ORDER BY mt.Id 

Если я применяю TOP к исходному запросу, он замедляется. Если нет TOP, он быстро возвращает все 1000 записей.

Если я удалю предложение WHERE и получу ТОП 50, это снова быстро.

Также пробовал, так как другие посты предлагают заменить ГДЕ на НЕ СУЩЕСТВУЕТ. Не помогло.

Есть ли какие-либо общие возможные причины или это действительно специфично для моей базы данных? Я полагаю, что если это конкретная информация, я не могу рассчитывать на помощь, потому что мне не разрешено делиться планами выполнения.

EDIT:

В предложении WHERE было два других условия, которые, на мой взгляд, были действительно пренебрежимо малы, но как только я их прокомментировал, первоначальный запрос возвращается через 50 мс !!!!!!!

SELECT TOP 50 AppId FROM Application ap
        LEFT OUTER JOIN MissingThings mt on mt.AppId = ap.AppId
        WHERE mt.AppId is NULL
AND ap.IsOrderFinished = 1
AND ap.IsAssigned = 2
        ORDER BY mt.Id 

Добавлен некластеризованный индекс для IsOrderFinished и IsAssigned - не помогает ни для обоих, ни для одного из индексов.

Дополнительные результаты:

Быстрый по убыванию (50 мс!) ORDER BY mt.Id DESC (перейти к цифре)

1 Ответ

1 голос
/ 03 июля 2019

Иногда я не могу сделать работу оптимально полным запросом, но я могу сделать оптимальную их части. Затем вместо того, чтобы пытаться оптимизировать полный запрос, я просто перемещаю детали во временную таблицу и использую их для построения полного запроса.

Это должно выполняться за 300 мс вместо 1,5 с

SELECT AppId 
into #Application
FROM Application ap
     LEFT OUTER JOIN MissingThings mt on mt.AppId = ap.AppId
WHERE mt.AppId is NULL
ORDER BY ap.AppId 

SELECT TOP 50 * FROM #Application

DROP TABLE #Application

Мы также пытаемся немного ускорить его, используя ваш самый быстрый запрос. Это должно выполняться ближе к 100 мс.

CREATE TABLE #Application (AppId INT, MissingAppId INT)
CREATE CLUSTERED INDEX #IX_Application ON #Application (MissingAppId, AppId)

INSERT INTO #Application (AppId, MissingAppId)
SELECT ap.AppId, mt.AppId
FROM Application ap
     LEFT OUTER JOIN MissingThings mt on mt.AppId = ap.AppId

SELECT TOP 50 * 
FROM #Application
WHERE MissingAppId IS NULL
ORDER BY AppId

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