2013-06-25 44 views
2

分區視圖我有以下幾點看法沒有檢查

create view V(CategoryId, ...) 
as 
select 1, .... from T1 union all 
select 2, .... from T2 union all 
select 3, .... from T3 union all 
select 4, .... from T4 union all 
select 5, .... from T5 union all 
... 

我沒有列CategoryId添加下劃線表,因爲每個表都有固定值,因此我不能添加Check(CategoryId = 1)由於列沒有按物理上是存在的。

以下查詢將掃描所有表。這是一種讓執行計劃只掃描一個查詢表的方法嗎?

declare @id tinyint = (....); 
select * from V where CategoryId = @id and ... 
+0

你肯定* *它會掃描所有的表?看看不應該掃描的實際執行計劃和「執行次數」。或'SET STATISTICS IO ON'的輸出。另外我認爲你不打算在你的示例視圖定義中有多個'T1'引用? –

+0

我已經更新了這個問題。 sql'select ... from CategoryId = 1'將只掃描一個表。但是,sql'declare @id tinyint =(...);選擇... from CategoryId = @ id'將掃描所有表格。 – ca9163d9

+0

即使您的編輯我沒有看到它掃描所有的表。它們出現在計劃中,但表訪問在它之前有一個帶有啓動謂詞的過濾器,因此只有在參數值需要時纔會執行。你是否檢查了我在第一條評論中提到的兩件事情? –

回答

4

下面的查詢將掃描所有的表。這是一種讓 執行計劃只掃描查詢表的一個表的方法嗎?

首先檢查確實發生了這種情況。

CREATE TABLE T1(X INT) 
CREATE TABLE T2(X INT) 
CREATE TABLE T3(X INT) 

GO 

CREATE VIEW V(CategoryId, X) 
AS 
    SELECT 1, X 
    FROM T1 
    UNION ALL 
    SELECT 2, X 
    FROM T2 
    UNION ALL 
    SELECT 3, X 
    FROM T3 

然後運行

SET STATISTICS IO ON; 

DECLARE @id TINYINT = 1; 

SELECT * 
FROM V 
WHERE CategoryId = @id 

返回

Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0 
Table 'T1'. Scan count 1, logical reads 0, physical reads 0 

表示既不T2T3被訪問。該計劃看起來像

enter image description here

過濾運營商有啓動斷言,只有執行掃描下如果@id值匹配相關的計劃的一部分。

在實際執行計劃中,如果您查看T2T3掃描操作員的屬性,則「執行次數」顯示爲0

你也可以評估

DECLARE @id TINYINT = 1; 

SELECT * 
FROM V 
WHERE CategoryId = @id 
OPTION (RECOMPILE) 
+0

謝謝,看來這是執行計劃不準確的例子之一。我在這個問題上修改了問題。 http://stackoverflow.com/questions/17308267/partitioned-view-execution-plan – ca9163d9