Будет ли SQL Server 2008 оптимизировать объединение, если не нужно? - PullRequest
0 голосов
/ 05 сентября 2011

В следующем запросе объединение с таблицей title_deed требуется только для критерия поиска title_deed_no, и из него не выбираются никакие поля. Если параметр @titleDeedNumber равен нулю, будет ли выполняться соединение? Как бы это повлияло на производительность? Я пытаюсь заменить динамическую генерацию большой некрасивой строки T-SQL, и код, который делает это, добавляет соединение, только если указано значение title_deed_no.

DECLARE @registrarId nchar(1)
DECLARE @titleDeedNumber nvarchar(50)

SELECT TOP 100
        vw.*
FROM    ACC.dbo.vw_Property_Nad vw
        INNER JOIN title_deed td ON ( @titleDeedNumber IS NULL )
                                    OR ( td.Prop_ID = vw.prop_id )
WHERE   vw.Prop_ID IS NOT NULL
        AND Registrar = isnull(@registrarId, vw.Registrar)
        AND td.title_deed_no = isnull(@titleDeedNumber, td.title_deed_no)

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

Ответы [ 2 ]

2 голосов
/ 05 сентября 2011

В этом случае, вероятно, нет.

Вам лучше использовать:

  • a EXISTS not JOIN (т. Е. Semi-join не equi-join)
  • (vw.Registrar = @registrarId OR @registrarId IS NULL)
  • То же самое для td.title_deed_no в EXISTS

Также

  • TOP без ORDER BY бесполезен
  • Ваше условие JOIN подразумевает CROSS JOIN -> вам нужно DISTINCT, чтобы оно заработало
  • vw подразумевает представление -> запрос более сложный, чем вы ожидаете.Представление - это макрос, который расширяется

Я бы также рассмотрел IF или UNION ALL

SELECT
        vw.*
FROM    ACC.dbo.vw_Property_Nad vw
WHERE   vw.Prop_ID IS NOT NULL
        AND (vw.Registrar = @registrarId OR @registrarId IS NULL)
        AND @titleDeedNumber IS NULL
UNION ALL
SELECT
        vw.*
FROM    ACC.dbo.vw_Property_Nad vw
WHERE   vw.Prop_ID IS NOT NULL
        AND (vw.Registrar = @registrarId OR @registrarId IS NULL)
        AND @titleDeedNumber IS NOT NULL
        AND EXISTS (...)
ORDER BY something
1 голос
/ 05 сентября 2011

Я не уверен, что вы хотите оптимизировать объединение. Это будет означать, что у вас будет как минимум два разных плана в зависимости от параметра, что означает, что он не будет оптимальным (или потенциально даже действительным), если параметр предоставлен, а кэшированный план хранится с NULL (или наоборот). ). Если это то, чего вы в конечном итоге хотите достичь, используйте две разные хранимые процедуры и позвольте приложению решать, какую из них вызывать, основываясь на том, заполнен параметр или нет.

Но делайте это только в том случае, если вы действительно наблюдаете значительные различия в плане / производительности. Как утверждает @gbn, я сомневаюсь, что в этом случае вы увидите огромную разницу в производительности, если только таблица с заголовком не будет огромной и неиндексированной (или не проиндексированной оптимально). Типичный подход к этому - сравнить значение ИЛИ проверить, что значение равно NULL. Многопроцессный подход гораздо более утомителен для поддержания, как правило, с небольшой выгодой, даже с одним необязательным параметром, и он просто соединяется с более чем одним необязательным параметром.

Для очень хорошего фонового чтения, ознакомьтесь со статьей Эрланда Соммарскога о Условиях динамического поиска ( версия, специфичная для 2008 ).

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