2011-09-22 36 views
3

我目前正在测试分区配置,使用实际的执行计划来识别RunTimePartitionSummary/PartitionsAccessed信息。SQL分区消除

当使用字面值对分区列运行查询时,分区消除工作正常(使用=和< =)。但是,如果将查询连接到查找表,并将分区列< =添加到查找表中的列,并用另一个条件限制查找表(这样只返回一行,就好像它是文字一样)消除不会发生。

这似乎只发生在连接标准为< =而不是=时,即使结果相同。反转逻辑和使用之间也不起作用,也不使用交叉应用函数。

编辑:(再现步骤)

确定在这里你去!

--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. 

--edited使产生的范围相同,以确保考试公平

+1

请更详细地陈述SQL Server版本 –

+1

+1什么是SELECT @@ VERSION;因为SPs /累积更新中已经发布了几个分区问题修复程序。 –

+0

2008 SP2 - 10.0.4000.0(X64) – SQLGobbleDeGook

回答

0

是有意义的查询扫描所有分区。

所有分区都参与谓词T.StartDate <= C.CalendarDate,因为查询计划程序不可能知道C.CalendarDate可能采用哪些值。