Использование переменных увеличивает сканирование и логическое чтение - PullRequest
1 голос
/ 11 августа 2011

Я не могу этого понять.У меня есть запрос, и если я жестко закодирую число для EntityType в запросе, это статистика ввода-вывода

Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'FranchiseAgreement'. Scan count 1, logical reads 157, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Address'. Scan count 1, logical reads 5485, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'County'. Scan count 1, logical reads 126, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'State'. Scan count 0, logical reads 505, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Country'. Scan count 0, logical reads 488, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'City'. Scan count 0, logical reads 630, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ARTaxMasterfile'. Scan count 4, logical reads 36, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ELMasterfile'. Scan count 1, logical reads 205, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

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

Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ELMasterfile'. Scan count 1, logical reads 205, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
***Table 'FranchiseAgreement'. Scan count 539932, logical reads 1750032, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Address'. Scan count 1, logical reads 5485, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'County'. Scan count 0, logical reads 481, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'State'. Scan count 0, logical reads 505, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Country'. Scan count 0, logical reads 488, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'City'. Scan count 0, logical reads 630, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ARTaxMasterfile'. Scan count 4, logical reads 36, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

DECLARE @BalanceIdEL SMALLINT
SET @BalanceIdEL = 14

PRINT 'Version 5'
SELECT Stores.*, Tax.ARTaxMasterFileId
FROM
(   -- Get The Addres of Each Lease
    SELECT 
        E.LeaseNum
    ,   E.LeaseDate
    ,   A.CountryCode
    ,   A.StateProvCode
    ,   A.County
    ,   A.City
    FROM 
        ELMasterFile E
    INNER JOIN
        FranchiseAgreement F
        ON  E.EntityId = F.FranchiseID
        AND E.EntityType = 7
    INNER JOIN
        Address A
        ON  F.FranchiseNum = A.EntityId
        AND F.SatelliteNum = A.SatelliteNum
        AND A.EntityType = 5 -- Store
        AND A.AddressType = 3 -- Store Address  
    )  Stores
INNER JOIN 
    -- Get the Taxes at each Level, Country, State, County and City
    (SELECT A.*, C.CountryCode, '' AS StateProvCode, '' AS CountyName, '' AS CityName
    FROM ARTaxMasterFile A
    INNER JOIN
        COMMON.dbo.Country C
        ON A.ARTaxLevelTypeId = C.CountryId 
    where BalanceId = @BalanceIdEL
    and ARTaxLevelType = 1
    UNION ALL
    SELECT A.*, S.CountryCode, S.StateProvCode AS StateProvCode, '' AS CountyName, '' AS CityName
    FROM ARTaxMasterFile A
    INNER JOIN
        COMMON.dbo.State S
        ON A.ARTaxLevelTypeId = S.StateId 
    where BalanceId = @BalanceIdEL
    and ARTaxLevelType = 2
    UNION ALL
    SELECT A.*, C.CountryCode, C.StateProvCode AS StateProvCode,  C.CountyName AS CountyName, '' AS CityName
    FROM ARTaxMasterFile A
    INNER JOIN
        COMMON.dbo.County C
        ON A.ARTaxLevelTypeId = C.CountyId 
    where BalanceId = @BalanceIdEL
    and ARTaxLevelType = 3
    UNION ALL
    SELECT A.*, Country.CountryCode, State.StateProvCode AS StateProvCode,  County.CountyName AS CountyName, City.CityName AS CityName
    FROM ARTaxMasterFile A
    INNER JOIN
        COMMON.dbo.City City
        ON A.ARTaxLevelTypeId = City.CityId 
    INNER JOIN
        COMMON.dbo.County County
        ON City.CountyId = County.CountyId
    INNER JOIN
        COMMON.dbo.State State
        ON City.StateId = State.StateId
    LEFT OUTER JOIN
        COMMON.dbo.Country Country
        ON City.CountryId = Country.CountryId       
    where BalanceId = @BalanceIdEL
    and ARTaxLevelType = 4) Tax
    ON  (Stores.CountryCode = Tax.CountryCode
        AND Tax.StateProvCode = ''
        AND Tax.CountyName = ''
        AND Tax.CityName = '')
    OR 
        (Stores.CountryCode = Tax.CountryCode
        AND Stores.StateProvCode = Tax.StateProvCode 
        AND Tax.CountyName = ''
        AND Tax.CityName = '')
    OR 
        (Stores.CountryCode = Tax.CountryCode
        AND Stores.StateProvCode = Tax.StateProvCode 
        AND Stores.County = Tax.CountyName 
        AND Tax.CityName = '')
    OR 
        (Stores.CountryCode = Tax.CountryCode
        AND Stores.StateProvCode = Tax.StateProvCode 
        AND Stores.County = Tax.CountyName 
        AND Stores.City =Tax.CityName)
WHERE Tax.StartDate <= GETDATE()
AND Tax.StartDate > Stores.LeaseDate 

Самое смешное, что параметр не используется в этой таблице.с 14 запрос выполняется в 2 раза быстрее.

1 Ответ

3 голосов
/ 11 августа 2011

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

По этой причине я больше не использую переменные в качестве констант - теперь я использую константы с комментариями

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