1

我有这张表(TableA):

(
    [FieldA] [int] NOT NULL,
    [FieldB] [int] NOT NULL,
    [Value] [float] NULL
CONSTRAINT [PK_TableA] PRIMARY KEY CLUSTERED 
(
    [FieldA] ASC,
    [FieldB] ASC
)

几乎没有不同的 FieldA 值,假设 FieldA 可以是 {1,2,3,4,5,6}。

为什么这个查询会导致全表扫描:

SELECT COUNT(*) FROM TableA WHERE FieldB = 1

虽然这不是:

SELECT COUNT(*) FROM TableA WHERE FieldB = 1 where FieldA in (1,2,3,4,5,6)

Sql Server 不能优化这个吗?如果我有 TableB,其中 FieldA 是一个 PK,并且我加入了 TableB 和 TableA,则查询将与第二个查询类似地运行。

4

2 回答 2

1

您创建的聚集索引基于两列。如果您只对其中一个列进行查找,SQL Server 无法生成“键”值以在该索引的查找过程中使用,因此它回退到表扫描方法。

尽管 FieldA 可以包含的值范围非常小,但 SQL 优化器不会查看该值范围来确定它是否可以从您提供的信息中“捏造”一个键。

如果要提高第一个查询的性能,则必须在 FieldB 上创建另一个索引。如果,如您所说,FieldA 中的不同值并不多,并且您仅在 FieldB 上进行大部分查找,则您可能需要考虑将聚集索引移动到仅在 FieldB 上构建并在 FieldA 上生成唯一索引和场 B.

于 2012-03-24T13:13:48.870 回答
1

显然,我正在寻找的是一种跳过扫描优化,它在 Oracle 上可用,但在 SQL Server 上不可用。如果缺少前沿列谓词,跳过扫描可以利用索引:http: //social.msdn.microsoft.com/Forums/eu/transactsql/thread/48de15ad-f8e9-4930-9f40-ca74946bc401

于 2012-04-11T11:52:12.237 回答