2009-08-27 2 views
4

У меня есть эти два запроса:Плохая сгруппированная скорость поиска индекса?

SELECT SELECT NamesRecord.NameID, NamesRecord.FulfillmentAddressID NameFulfillmentAddressID, ContractRecord.FulfillmentAddressID, ContractRecord.BillingAddressId 
FROM Magnet.dbo.ContractRecord ContractRecord 
    INNER JOIN Magnet.dbo.NamesRecord NamesRecord 
     ON NamesRecord.NameId = ContractRecord.DonorId 
WHERE NameID > -1 
AND (EXISTS (
     SELECT 1 
     FROM Magnet.dbo.AddressRecord AddressRecord 
     WHERE AddressRecord.AddressId = ContractRecord.FulfillmentAddressId 
     AND BuildingFloor LIKE 'M%') 
    OR EXISTS (
     SELECT 1 
     FROM Magnet.dbo.AddressRecord AddressRecord 
     WHERE AddressRecord.AddressId = ContractRecord.BillingAddressId 
     AND BuildingFloor LIKE 'M%')) 


SELECT SELECT NamesRecord.NameID, NamesRecord.FulfillmentAddressID NameFulfillmentAddressID, ContractRecord.FulfillmentAddressID, ContractRecord.BillingAddressId 
FROM Magnet.dbo.ContractRecord ContractRecord 
    INNER JOIN Magnet.dbo.NamesRecord NamesRecord 
     ON NamesRecord.NameId = ContractRecord.DonorId 
WHERE NameID > -1 
AND (EXISTS (SELECT 1 
     FROM Magnet.dbo.AddressRecord AddressRecord 
     WHERE AddressRecord.AddressId IN (ContractRecord.FulfillmentAddressId, ContractRecord.BillingAddressId) 
     AND BuildingFloor LIKE 'M%')) 

Первый запрос работает более чем в 10 раз быстрее, чем второй. В соответствии с Планом выполнения первый запрос использует два кластерных индексатора с «BuildingFloor LIKE« M% »в качестве предиката и индексный поиск в ContractRecord для каждого из подвыборников в предложении WHERE (40% к югу от выбора).

Во втором запросе используется кластерный указатель поиска с «BuildingFloor LIKE» M% '»в качестве предиката и предикат поиска для ограничений AddressId (96% стоимости). Оценочное количество строк также полностью исключено (по сравнению с 250 действительными против 1).

Как повысить производительность второго запроса? Могу ли я заставить SQL Server выбрать альтернативную стратегию или мне нужно изменить индексы в таблицах?

ответ

8

Подзапросы в строке медленно, как и дизъюнктивные (or) условия фильтра. Избавьтесь от подзапросов целиком, и если вы используете предикат or в фильтре, вы можете подумать о его замене union. Внутренне, in преобразуется в or.

select 
    NamesRecord.NameId 
from (
    select 
     ContractRecord.DonorId, 
     ContractRecord.FulfillmentAddressId as AddressId 
    from Magnet.dbo.ContractRecord ContractRecord 
    union 
    select 
     ContractRecord.DonorId, 
     ContractRecord.BillingAddressId as AddressId 
    from Magnet.dbo.ContractRecord ContractRecord 
) ContractRecordInfo 
join Magnet.dbo.NamesRecord NamesRecord on 1=1 
    and NamesRecord.NameId = ContractRecordInfo.DonorId 
    and NamesRecord.NameId > -1 
join Magnet.dbo.AddressRecord AddressRecord on 1=1 
    and AddressRecord.AddressId = ContractRecordInfo.AddressId 
    and AddressRecord.BuildingFloor like 'M%' 
+0

Кажется, что разница в возвращаемых наборах результатов. Я сделаю еще несколько исследований, прежде чем опубликовать комментарий. – ilitirit

+0

ОК, я нашел проблему, и это была моя ошибка. Я не включал несколько требуемых столбцов в оператор select. – ilitirit

+0

Насколько быстрее это? – yfeldblum

Смежные вопросы