2011-09-22 62 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可能採用哪些值。