CREATE TABLE #174860 (
PK INT NOT NULL,
COL1 INT NOT NULL,
COL2 INT NOT NULL,
PRIMARY KEY (PK)
);
INSERT INTO #174860 WITH (TABLOCK)
SELECT RN
, RN % 1000
, RN % 10000
FROM
(
SELECT TOP 1000000 ROW_NUMBER () OVER (ORDER BY (SELECT NULL)) RN
FROM master..spt_values v1,
master..spt_values v2
) t;
CREATE INDEX IX_174860_IX ON #174860 (COL1) INCLUDE (COL2);
让我们将一百万行与几列一起放入临时表中:
在这里,我在列上有一个聚集索引(默认情况下)
PK
。有一个非聚集索引COL1
,其键列为COL1
和 包括COL2
。考虑以下查询:
这里我没有使用
BETWEEN
,因为 Aaron Bertrand 一直在讨论这个问题。SQL Server 优化器应该如何查询?好吧,我知道过滤器
PK
会将结果集减少到五行。SQL Server 可以使用聚集索引跳转到这五行,而不是读取表中的所有百万行。但是,聚集索引只有 PK 列作为键列。将行读入内存后,我们需要在COL2
. 这里,PK
是一个搜索谓词,COL2
是一个谓词。SQL 服务器使用 seek 谓词找到五行,并使用普通谓词进一步将这五行减少为一行。
如果我以不同方式定义聚集索引:
并运行相同的查询,我得到不同的结果:
WHERE
在这种情况下,SQL Server 可以使用子句中的两个列进行查找。使用键列从表中读取一行。再举一个例子,考虑这个查询:
IX_174860_IX 索引是一个覆盖索引,因为它包含查询所需的所有列。但是,只有
COL1
一个关键列。SQL Server 可以使用该列查找具有匹配COL1
值的 1000 行。它可以进一步过滤列上的那些行,COL2
以将最终结果集减少到 0 行。