【发布时间】:2015-01-25 10:04:40
【问题描述】:
我创建了一个表来测试正在读取的逻辑块的数量和查询优化器选择的执行计划,比较该表有索引和没有索引时的查询。
测试表是
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 次扫描读取和索引扫描算法
问题是:如果查询优化器选择了运行查询的最佳方式,那么如果表扫描可以读取更少的块,为什么还要选择索引扫描呢?
【问题讨论】:
-
你只是在读取所有的行——索引没有做任何事情。添加一个 WHERE 子句,看看会发生什么。
-
查询优化器预测运行查询的最佳方式。它通常不可能在不检查数据的情况下知道最好的方法,这会破坏目的。因此,它不会总是选择绝对最佳的策略,但选择一个非常好的策略应该是相当可靠的。您的数据表明并非如此。
-
您的数字是 实际 读取还是 估计 读取?在这么小的表上,索引不太可能特别有用。
-
@GordonLinoff,我使用 SET STATISTICS IO ON 获得的那些数字。检查我在上面答案中的评论。这是我对这些数字的怀疑
标签: sql sql-server indexing query-optimization sql-execution-plan