2011-09-22 3 views
3

현재 실제 실행 계획을 사용하여 RunTimePartitionSummary/PartitionsAccessed 정보를 식별하는 파티션 구성을 테스트하고 있습니다.SQL 파티션 제거

분할 열에 대해 리터럴로 쿼리를 실행하면 파티션 제거가 잘 작동합니다 (= 및 < = 사용). 그러나 쿼리가 조회 테이블에 조인 된 경우 분할 테이블 < =을 조회 테이블의 열에 추가하고 조회 테이블을 다른 조건으로 제한하여 (리터럴 인 것처럼 하나의 행만 반환되도록) 제거가 발생하지 않습니다.

결과가 같더라도 조인 조건이 =보다 < = = 일 경우에만 발생합니다. 논리를 반전하고 사이를 사용하는 것은 작동하지 않으며 교차 적용 기능을 사용하지도 않습니다.

편집 : (생식 단계)

여기 당신이 가서 OK! 결과를 만들 --edited

--Create sample function 
CREATE PARTITION FUNCTION pf_Test(date) AS RANGE RIGHT FOR VALUES ('20110101','20110102','20110103','20110104','20110105') 
--Create sample scheme 
CREATE PARTITION SCHEME ps_Test AS PARTITION pf_Test ALL TO ([PRIMARY]) 
--Create sample table 
CREATE TABLE t_Test 
    (
     RowID int identity(1,1) 
     ,StartDate date NOT NULL 
     ,EndDate date NULL 
     ,Data varchar(50) NULL 
    ) 
ON ps_Test(StartDate) 
--Insert some sample data 
INSERT INTO t_Test(StartDate,EndDate,Data) 
VALUES 
    ('20110101','20110102','A') 
    ,('20110103','20110104','A') 
    ,('20110105',NULL,'A') 
    ,('20110101',NULL,'B') 
    ,('20110102','20110104','C') 
    ,('20110105',NULL,'C') 
    ,('20110104',NULL,'D') 

--Check partition allocation 
SELECT *,$PARTITION.pf_Test(StartDate) AS PartitionNumber FROM t_Test 

--Run simple test (inlcude actual execution plan) 
SELECT 
    * 
    ,$PARTITION.pf_Test(StartDate) 
FROM t_Test 
WHERE StartDate <= '20110103' AND ISNULL(EndDate,getdate()) >= '20110103' 
--<PartitionRange Start="1" End="4" /> 

--Run test with join to a lookup (with CTE for simplicity, but doesnt work with table either) 
WITH testCTE AS 
    (
     SELECT convert(date,'20110101') AS CalendarDate,'A' AS SomethingInteresting 
     UNION ALL 
     SELECT convert(date,'20110102') AS CalendarDate,'B' AS SomethingInteresting 
     UNION ALL 
     SELECT convert(date,'20110103') AS CalendarDate,'C' AS SomethingInteresting 
     UNION ALL 
     SELECT convert(date,'20110104') AS CalendarDate,'D' AS SomethingInteresting 
     UNION ALL 
     SELECT convert(date,'20110105') AS CalendarDate,'E' AS SomethingInteresting 
     UNION ALL 
     SELECT convert(date,'20110106') AS CalendarDate,'F' AS SomethingInteresting 
     UNION ALL 
     SELECT convert(date,'20110107') AS CalendarDate,'G' AS SomethingInteresting 
     UNION ALL 
     SELECT convert(date,'20110108') AS CalendarDate,'H' AS SomethingInteresting 
     UNION ALL 
     SELECT convert(date,'20110109') AS CalendarDate,'I' AS SomethingInteresting 
    ) 

SELECT 
    C.CalendarDate 
    ,T.* 
    ,$PARTITION.pf_Test(StartDate) 
FROM t_Test T 
    INNER JOIN testCTE C 
     ON T.StartDate <= C.CalendarDate AND ISNULL(T.EndDate,getdate()) >= C.CalendarDate 
WHERE C.SomethingInteresting = 'C' --<PartitionRange Start="1" End="6" /> 

--So all 6 partitions are scanned despite only 2,3,4 being required, as per the simple select. 

공정 시험

+1

SQL Server –

+1

의 버전을 SP/누적 업데이트에서 파티셔닝 문제에 대한 몇 가지 수정 사항이 릴리스되었으므로 'SELECT @@ VERSION;'으로 명시하십시오. –

+0

2008 SP2 - 10.0.4000.0 (X64) – SQLGobbleDeGook

답변

0

그것은 쿼리가 모든 파티션을 스캔 할 의미가를 확인하기 위해 동일한 범위.

쿼리 플래너가 C.CalendarDate 값을 알 수 없으므로 모든 파티션이 술어 T.StartDate <= C.CalendarDate에 포함됩니다.