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

1 回答 1

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访问。该计划看起来像

在此处输入图像描述

过滤器操作符有一个启动谓词,并且只有在@id与计划的该部分相关的值匹配时才执行下面的扫描。

在实际执行计划中,如果您查看T2T3扫描运算符的属性,则“执行次数”显示为0.

你也可以评估

DECLARE @id TINYINT = 1;

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