【问题标题】:Clustered versus nonclustered index in a SQL Server tableSQL Server 表中的聚集索引与非聚集索引
【发布时间】:2018-05-08 03:06:10
【问题描述】:

在数据仓库环境 (SQL Server 2008) 中工作,有一些表大约有 200 万行和 20 列。每天晚上,这些表都会被删除并重新创建。制作它们时,还会构建索引。由于某种原因,这些表上没有聚集索引。但是,有唯一的非聚集索引。似乎不合逻辑。有谁知道改变所有这些表的任何缺点,以便所有这些表都有一个聚集索引。应该会节省一些空间并且性能会更好。

有什么建议吗?

提前致谢。

【问题讨论】:

  • AFAIK all SQL Server 中的表都有一个聚集索引,无论你是否声明一个。
  • @TimBiegeleisen:我认为这不是真的。如果将 PK 创建为“非聚集”,SQL Server 将不会创建隐藏的聚集索引。您可能会将其与 MySQL 混淆吗?
  • @a_horse_with_no_name 默认情况下,SQL Server 将在后台创建聚集索引 (see here)。除了创建另一个命名索引之外,您确定可以将其关闭吗?
  • @TimBiegeleisen create table foo (id integer primary key nonclustered)
  • @a_horse_with_no_name 好的,但这仍然会创建一个索引。我想我的第一条评论用错了。

标签: sql-server indexing clustered-index


【解决方案1】:

确实聚集索引也有缺点。

我认为最被低估的缺点是我所说的聚集索引惩罚

如果表上没有任何聚集索引,则表示该表存储为堆表。所有非聚集索引都引用该堆表。

堆表的好处是存储在其中的行几乎不会移动——这与聚集索引不同,在聚集索引中,每一行都可以随时移动到不同的物理位置。

这种差异会影响非聚集索引,因为它们引用堆或聚集索引中的行:在堆的情况下,它们可以只将该行的物理位置存储在非聚集索引中(因为它们几乎从不改变)。如果有聚集索引,则非聚集索引存储聚集键。

如果您最终使用的是非聚集索引,则在堆或聚集索引中到达实际表的工作量是非常不同的:使用堆,您只需要一个物理 IO,使用聚集索引,您需要进行聚集索引查找,通常是 3-5 个逻辑 IO(取决于表大小)。

如果您有许多非聚集索引并且在没有仅索引扫描的情况下使用它们(这意味着遵循 RID 访问),聚集索引可能会严重影响性能。

我在这篇文章中写的更多细节:

http://use-the-index-luke.com/blog/2014-01/unreasonable-defaults-primary-key-clustering-key

【讨论】:

    猜你喜欢
    • 2013-08-20
    • 2012-10-01
    • 2011-03-24
    • 1970-01-01
    • 2014-04-27
    • 2013-03-22
    • 2020-08-04
    • 2011-11-30
    相关资源
    最近更新 更多