Sei*_*bar 69 sql sql-server indexing
由于a Table Scan和a Clustered Index Scan本质上都扫描了表中的所有记录,为什么Clustered Index Scan应该更好?
举个例子 - 当有很多记录时,下列内容之间的性能差异是什么?:
declare @temp table(
    SomeColumn varchar(50)
)
insert into @temp
select 'SomeVal'
select * from @temp
-----------------------------
declare @temp table(
    RowID int not null identity(1,1) primary key,
    SomeColumn varchar(50)
)
insert into @temp
select 'SomeVal'
select * from @temp
Mar*_*ett 77
在没有聚簇索引(堆表)的表中,数据页不会链接在一起 - 因此遍历页需要查找索引分配映射.
但是,集群表的数据页链接在双向链表中 - 使顺序扫描更快一些.当然,作为交换,你必须处理保持数据页顺序的开销INSERT,UPDATE和DELETE.但是,堆表需要对IAM进行第二次写入.
如果您的查询有一个RANGE运算符(例如SELECT * FROM TABLE WHERE Id BETWEEN 1 AND 100:),那么一个聚簇表(保证顺序)会更有效 - 因为它可以使用索引页来查找相关的数据页.堆必须扫描所有行,因为它不能依赖于排序.
当然,聚集索引允许您执行CLUSTERED INDEX SEEK,这对于性能来说非常优秀......没有索引的堆总是会导致表扫描.
所以:
对于您选择所有行的示例查询,唯一的区别是聚簇索引维护的双向链表.这应该使您的群集表比具有大量行的堆快一点.
对于具有WHERE可以(至少部分地)被聚集索引满足的子句的查询,由于排序,您将提前 - 因此您不必扫描整个表.
对于聚集索引不满意的查询,您甚至可以再次使用,唯一的区别是顺序扫描的双向链表.在任何一种情况下,你都不是最理想的.
对于INSERT,UPDATE和DELETE堆可能会赢得也可能不会赢.堆不必维护顺序,但需要第二次写入IAM.我认为相对性能差异可以忽略不计,但也依赖于数据.
Microsoft有一份白皮书,它将聚簇索引与堆上的等效非聚集索引进行比较(与上面讨论的完全不同,但是关闭).他们的结论基本上是在所有表上放置聚簇索引.我会尽力总结他们的结果(再次注意,他们确实在这里将非聚集索引与聚集索引进行比较 - 但我认为它相对可比):
INSERT 性能:由于堆需要第二次写入,聚簇索引会增加约3%.UPDATE 性能:由于堆需要第二次查找,聚簇索引赢得大约8%.DELETE 性能:聚簇索引由于需要进行第二次查找而需要大约18%,并且需要从堆的IAM进行第二次删除.SELECT性能:由于堆需要第二次查找,聚簇索引增加了大约16%.SELECT性能:由于堆的随机排序,聚簇索引赢得约29%.INSERT:由于聚簇索引的页面拆分,堆表在负载下赢了30%.http://msdn.microsoft.com/en-us/library/aa216840(SQL.80).aspx
Clustered Index Scan 逻辑和物理运算符扫描 Argument 列中指定的聚集索引。当存在可选的 WHERE:() 谓词时,仅返回满足该谓词的行。如果 Argument 列包含 ORDERED 子句,则查询处理器已请求按聚集索引对行的排序顺序返回行的输出。如果 ORDERED 子句不存在,存储引擎将以最佳方式扫描索引(不保证输出被排序)。
http://msdn.microsoft.com/en-us/library/aa178416(SQL.80).aspx
表扫描逻辑和物理运算符从 Argument 列中指定的表中检索所有行。如果 WHERE:() 谓词出现在 Argument 列中,则仅返回满足该谓词的行。
| 归档时间: | 
 | 
| 查看次数: | 40401 次 | 
| 最近记录: |