我创建了一个表来测试正在读取的逻辑块的数量以及查询优化器选择的执行计划,比较这个表有索引时的查询和不具有索引的查询。
测试表是
create table scan
(
id int identity(1, 1),
a varchar(10),
b varchar(10),
c varchar(10),
d varchar(10),
e varchar(10),
f varchar(10)
)
当我运行这些查询时:
select * from scan
select id from scan
我得到了88和58个逻辑读取,以及一个表扫描算法
然后我改变了表格,将pk约束和他的聚类id
alter table scan
add constraint fk_id primary key (id)
然后运行相同的查询:
select * from scan
select id from scan
我得到了90和60次扫描读取和索引扫描算法
问题是:如果查询优化器选择运行查询的最佳方式,那么为什么在表扫描可以读取较少块时选择索引扫描?
答案 0 :(得分:3)
创建主键约束时,默认情况下会将其设置为群集。这意味着您之前使用此密钥对您的堆进行了排序(在您的情况下为id
)。
表中的数据可以以两种方式之一存储:堆或聚簇索引。当后者被创建时,前者就消失了。因此,SQL Server无法对索引执行表扫描 - 它只能是索引扫描(聚集索引扫描,顺便说一句 - 这很重要)。
我知道这可能听起来令人困惑,但尝试阅读有关聚集索引的一些基础知识 - 这可能有所帮助。