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)しませんでした。列が物理的に存在しないため、追加できません。

次のクエリは、すべてのテーブルをスキャンします。クエリのテーブルの 1 つだけを実行計画にスキャンさせる方法はありますか?

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

1 に答える 1

4

次のクエリは、すべてのテーブルをスキャンします。クエリのテーブルの 1 つだけを実行計画にスキャンさせる方法はありますか?

まず、これが実際に起こっていることを確認してください。

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、アクセスされていません。計画は次のようになります

ここに画像の説明を入力

フィルター演算子には起動述語があり、 の値が@id計画のその部分に関連するものと一致する場合にのみ、その下のスキャンを実行します。

実際の実行計画では、T2and T3scan 演算子のプロパティを見ると、「実行回数」が として表示され0ます。

評価することもできます

DECLARE @id TINYINT = 1;

SELECT *
FROM   V
WHERE  CategoryId = @id 
OPTION (RECOMPILE)
于 2013-06-25T21:29:04.207 に答える