2009-08-27 2 views
4

나는이 두 개의 쿼리를 가지고 : 첫 번째 쿼리가 10 배 이상 빠른 초 이상 실행클러스터 된 인덱스 검색 성능이 좋지 않습니까?

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%')) 

. Execution Plan에 따르면 첫 번째 쿼리는 "BuildingFloor LIKE 'M %'"를 술어로 사용하는 두 개의 클러스터 된 인덱스 스캔을 사용하고 WHERE 절의 각 하위 선택 항목에 대해 ContractRecord에 대한 인덱스 검색을 수행합니다 (40 %의 비용 하위 선택).

두 번째 쿼리는 "BuildingFloor LIKE 'M %'"를 술어로 사용하고 "AddressId 제약 조건"(96 % 비용)에 대한 검색 조건자를 클러스터 된 인덱스 검색을 사용합니다. 예상 행 수는 완전히 동일합니다 (실제 250 대 1 추정).

어떻게하면 두 번째 쿼리의 성능을 향상시킬 수 있습니까? SQL Server에서 대체 전략을 선택하도록 강요 할 수 있습니까? 아니면 테이블의 인덱스를 수정해야합니까?

답변

8

행 단위 하위 쿼리가 느리기 때문에 분리 필터 (or) 필터 조건이 적용됩니다. 서브 쿼리를 완전히 없애고 필터에 or 조건자를 사용하는 경우 union으로 바꾸는 것이 좋습니다. 내부적으로 inor으로 번역됩니다.

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

관련 문제