没有Check的分区视图

时间:2013-06-25 21:05:34

标签: sql-server sql-server-2008

我有以下观点

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

1 个答案:

答案 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)