【问题标题】:cost of non-clustered indexes非聚集索引的成本
【发布时间】:2011-06-11 21:29:14
【问题描述】:

如果我在表上创建非聚集索引,SQL Server 是否会在该表中复制数据并单独存储?我只是在考虑创建非聚集索引的成本。我猜索引中使用的那个键选择会更快,但所有插入、更新和删除都会很慢,因为 sql server 必须维护两个数据副本。我的理解正确吗?

【问题讨论】:

  • 其他数据副本存储在何处以及如何存储?这就是我想要理解的
  • 如果你想亲自看看这些东西,我建议你试试 SQL Internals Viewer(在 codeplex 上)

标签: sql-server indexing


【解决方案1】:

SQL Server 不会复制表中的所有数据,只会复制索引列和任何“覆盖”列中包含的数据,以及额外的开销数据。

是的,插入/更新会稍微慢一些,但是您可能因没有选择索引而产生的成本可能远远超过这一点。在大多数情况下,除非您定期每秒插入数百/数千行,否则您可能不会注意到通过在表上设置适当数量的索引对插入/更新产生太大影响。

我们尝试限制生产数据库上的索引,但在我们的报告数据库上使用更多的索引,这些索引是从我们的生产数据库复制而来的。没有注意到在报告数据库上有许多索引(用于插入/更新)的开销。

【讨论】:

  • @ivo 索引页 do 会复制此答案中所述的数据(键列、行定位符、包含的列)。叶级索引页在行存储方面与数据页非常相似(格式有一些细微差别,例如没有状态位 B 并且并不总是有 NULL BITMAP)。要回答您的“为什么”,请考虑随机 I/O 与顺序 I/O。
  • @ivo 我可以向你保证我的描述是完全正确的。 (我不确定您为什么要谈论“整行”,我非常明确地声明了key columns, row locator, included columns)它存储了一个行定位器(否则为堆或聚集索引键的文件:页面:偏移量)但只需要使用如果索引没有完全覆盖。当它确实需要使用它时,这是一个非常昂贵的随机 I/O 密钥查找。您可能想阅读sqlblog.com/blogs/kalen_delaney/archive/2010/03/07/…
  • @ivo s - 我的脑海里闪过一个想法,也许我们在谈论不同的目的,但我认为我们不是。您是否曾经使用DBCC INDDBCC PAGE 实际查看过SQL Server 中的索引页?
  • @ivo 抱歉,但是通过查看 mdf 文件的大小来尝试找出正在发生的事情的建议是可笑的。 mdf 文件根据增长率分块增长,因此在任何时候都可能有未使用的可用空间。该文件分为范围和页面DBCC PAGE 确实显示了特定页面的内容(为人类消费而格式化)我建议你阅读这个(非常有据可查的)区域。
  • 我认为 ivo 删除了他所有的 cmets。我可以拼凑出他一定说的话,所以……干得好,马丁!
【解决方案2】:

非聚集索引的数据不会“复制”。 创建各种“映射”(有时仅使用索引列的完整副本)以使该字段上的某些查询的查找速度更快。对于这方面的基本指导,请考虑 B-Tree http://en.wikipedia.org/wiki/B-tree 不同节点位于众所周知的位置,您可以根据查询确定从哪里开始查找。 是的,您需要花费一些资源来创建/维护地图……但是您在搜索上花费了多少时间?

SQL Server 中聚簇索引和非聚簇索引最根本的区别在于,聚簇索引描述了磁盘上行的物理存储顺序……这就是为什么顺序聚簇索引通常更适合插入性能的原因.

另一方面,对于非聚集索引,您需要衡量搜索性能与插入性能/磁盘空间成本的重要性。我通常会在任何常用搜索字段上使用索引。 如果同一个字段有非常频繁的插入,它会变得有点复杂,但我从来没有亲自处理插入性能来说服我不使用索引。

【讨论】:

  • @Matthew。对于这个非集群索引,磁盘上究竟存储了什么。是存储在磁盘上的这种“映射”吗?SQL Server 在内存中也为这张表提供了这个映射的副本?
  • +非常正确,btree结构必须先学习+1以获得很好的答案,然后您可以进入实现细节msdn.microsoft.com/en-us/library/ms177484.aspx
  • @imak,根据 ivo 发布的链接,SQL Server 存储索引页而不是非聚集索引叶子的数据页。索引页存储在磁盘上(并且可能根据使用情况加载到内存中),但我不能确切地说出在哪里。我猜在数据库文件本身
  • 顺序值上的聚集索引比非顺序值上的聚簇索引具有更好的插入性能,因为它避免了分页,而不是因为它“描述了磁盘”。
  • @Stephanie Page,聚集索引确实描述了磁盘上行的物理顺序。这是有据可查的,也是聚集索引的 GUID 会降低插入性能的主要原因之一:通过非顺序值来处理物理数据。根据msdn.microsoft.com/en-us/library/aa933131(v=sql.80).aspx“聚集索引确定表中数据的物理顺序”,我觉得很讽刺的是,我得到了公认的答案和如此多的反对票。
【解决方案3】:

答案还取决于您是否使用covering index,它将包含表中部分或全部列的副本。上面链接到的文章很好地解释了原因。

【讨论】:

    猜你喜欢
    • 2013-08-07
    • 2020-08-04
    • 1970-01-01
    • 2021-01-14
    • 1970-01-01
    • 2016-01-05
    • 2011-04-05
    • 2015-07-31
    相关资源
    最近更新 更多