【问题标题】:What are the differences between a clustered and a non-clustered index?聚集索引和非聚集索引有什么区别?
【发布时间】:2010-09-10 15:20:17
【问题描述】:

clusterednon-clustered index 有什么区别?

【问题讨论】:

  • 每个表只能有一个聚集索引。但是还有很多其他的区别......
  • 聚集索引实际上描述了记录物理存储在磁盘上的顺序,因此您只能拥有一个。非聚集索引定义的逻辑顺序与磁盘上的物理顺序不匹配。
  • Clustered 基本上意味着数据在表中的物理顺序。这就是为什么每张桌子只能有一个。非集群意味着它“只是”一个逻辑顺序。
  • @biri 什么是“逻辑”顺序?非聚集索引按物理顺序存储索引键,并存储指向表的指针,即聚集索引键。
  • @Stephanie Page:从表格的角度来看是合乎逻辑的。当然,非聚集索引在索引本身中是物理排序的。

标签: sql-server indexing clustered-index non-clustered-index


【解决方案1】:

聚集索引

  • 聚集索引检索速度更快,插入速度更慢 和更新。
  • 一张表只能有一个聚集索引。
  • 不需要额外的空间来存储逻辑结构。
  • 确定数据在磁盘上的存储顺序。

非聚集索引

  • 非聚集索引在检索数据时速度较慢,在检索数据时速度较快 插入和更新。

  • 一个表可以有多个非聚集索引。

  • 需要额外的空间来存储逻辑结构。

  • 对磁盘上存储数据的顺序没有影响。

【讨论】:

    【解决方案2】:

    优点:

    聚集索引适用于范围(例如,从 my_table 中选择 *,其中 my_key 在 @min 和 @max 之间)

    在某些情况下,如果您使用 orderby 语句,DBMS 将不必进行排序工作。

    缺点:

    聚集索引可能会减慢插入速度,因为如果新键不按顺序插入,则必须在放入记录时修改记录的物理布局。

    【讨论】:

      【解决方案3】:

      集群基本上意味着数据在表中的物理顺序。这就是为什么每张桌子只能有一个。

      非集群意味着它“只是”一个逻辑顺序。

      【讨论】:

        【解决方案4】:

        聚集索引

        • 一个表中只能有一个聚集索引
        • 按顺序对记录进行排序并物理存储
        • 数据检索比非聚集索引更快
        • 不需要额外的空间来存储逻辑结构

        非聚集索引

        • 一个表中可以有任意数量的非聚集索引
        • 不影响物理顺序。为数据行创建逻辑顺序并使用指向物理数据文件的指针
        • 数据插入/更新比聚集索引快
        • 使用额外的空间来存储逻辑结构

        除了这些差异之外,您还必须知道,当表是非聚集的(当表没有聚集索引时)数据文件是无序的并且它使用堆数据结构作为数据结构。

        【讨论】:

          【解决方案5】:

          您可能已经了解了上述帖子的理论部分:

          -我们可以看到的聚集索引直接指向记录,即它的直接,因此搜索所需的时间更少。此外,它不会占用任何额外的内存/空间来存储索引

          -虽然,在非聚集索引中,它间接指向聚集索引,然后它会访问实际记录,由于它的间接性质,它需要更多的时间来访问。而且它需要自己的存储索引的内存/空间

          【讨论】:

            【解决方案6】:

            // 抄自MSDN,非聚集索引的第二点在其他答案中没有明确提及。

            集群

            • 聚集索引对表或视图中的数据行进行排序和存储 基于它们的关键值。这些是包含在 索引定义。每个表只能有一个聚集索引, 因为数据行本身只能以一种顺序存储。
            • 表中的数据行按排序顺序存储的唯一时间是 当表包含聚集索引时。当一个表有一个 聚集索引,该表称为聚集表。如果一个表 没有聚集索引,它的数据行存储在一个无序的 称为堆的结构。

            非集群

            • 非聚集索引具有与数据行分开的结构。一种 非聚集索引包含非聚集索引键值和
              每个键值条目都有一个指向包含 键值。
            • 从非聚集索引中的索引行指向数据行的指针 称为行定位器。行定位器的结构取决于 数据页是存储在堆还是聚簇表中。 对于堆,行定位器是指向行的指针。对于一个集群 表,行定位器是聚集索引键。

            【讨论】:

              【解决方案7】:

              聚集索引

              1. 一个表只能有一个聚集索引。
              2. 通常在主键上创建。
              3. 聚集索引的叶节点包含数据页。

              非聚集索引

              1. 一个表只能有 249 个非聚集索引(直到 sql version 2005 以后的版本最多支持 999 个非聚集索引)。
              2. 通常在任意键上制作。
              3. 非聚集索引的叶节点不包含数据页。相反,叶节点包含索引行。

              【讨论】:

                【解决方案8】:

                一个索引数据库有两个部分:一组物理记录,它们以任意顺序排列,一组索引标识读取记录的顺序,以产生按某种标准排序的结果。如果物理排列和索引之间没有关联,那么按顺序读取所有记录可能需要进行大量独立的单记录读取操作。因为一个数据库可能能够在比读取两个不连续记录的时间更短的时间内读取数十个连续记录,如果索引中连续的记录也连续存储在磁盘上,则性能可能会有所提高。指定索引是聚集的会导致数据库做出一些努力(不同的数据库在多少方面有所不同)来安排事情,以便索引中连续的记录组在磁盘上是连续的。

                例如,如果要从一个空的非集群数据库开始并以随机顺序添加 10,000 条记录,则这些记录可能会按照添加顺序添加到末尾。按索引顺序读取数据库需要 10,000 次单记录读取。但是,如果要使用集群数据库,系统可能会在添加每条记录时检查之前的记录是否是自己存储的;如果发现是这种情况,它可能会将该记录与数据库末尾的新记录一起写入。然后,它可以查看移动记录所在的插槽之前的物理记录,并查看后面的记录是否由它自己存储。如果发现是这种情况,它可以将该记录移至该位置。使用这种方法会导致许多记录成对组合在一起,从而可能使顺序读取速度几乎翻倍。

                实际上,集群数据库使用比这更复杂的算法。但是,需要注意的关键是在更新数据库所需的时间和按顺序读取数据库所需的时间之间进行权衡。维护集群数据库将显着增加以任何会影响排序顺序的方式添加、删除或更新记录所需的工作量。如果数据库被顺序读取的频率比更新的频率高得多,那么集群可能是一个巨大的胜利。如果它会经常更新但很少按顺序读取,则集群可能会消耗很大的性能,尤其是如果将项目添加到数据库的顺序与它们相对于集群索引的排序顺序无关。

                【讨论】:

                  【解决方案9】:

                  聚集索引

                  • 每桌只有一个
                  • 比非集群读取更快,因为数据是按索引顺序物理存储的

                  非聚集索引

                  • 每桌可多次使用
                  • 插入和更新操作比聚集索引更快

                  当使用使用索引的字段选择数据时,这两种类型的索引都会提高性能,但将减慢更新和插入操作。

                  由于插入和更新速度较慢,因此应在通常为增量的字段(即 Id 或时间戳)上设置聚集索引。

                  SQL Server 通常仅在其选择性高于 95% 时才使用索引。

                  【讨论】:

                  • 还有存储方面的考虑。在没有聚集索引的表中插入行时,这些行将背靠背存储在页面上,更新行可能会导致该行被移动到表的末尾,留下空白空间并使表和索引碎片化。跨度>
                  • 你不必关心什么是 x。您只需要知道,对于拥有数百万用户的应用,x 将非常重要
                  • 这纯粹是教条。它不是“因为数据是按顺序存储的,所以读取速度更快”。读取速度更快,因为您避免了索引读取和表读取。范围扫描(如果有意义的话)更快,因为数据是按顺序存储的。即聚类因子是完美的。
                  • 95% 的记录需要唯一的想法也是一种谬论。假设您有一个包含 1,000,000 行的表,并且您为包含 500,000 个键的列建立索引。 0% 是唯一的,但每个键返回一百万行中的 2 行。不管 0% 的记录是唯一的,这个索引绝对有用。
                  • “数据以索引顺序物理存储”你是什么意思?在一个层面上,这是微不足道的,因为数据页和索引叶页是一回事——所以很明显,一个的排序描述了另一个的排序。但是,这不一定是任何特定的顺序,例如索引键的顺序 stackoverflow.com/questions/1251636/…
                  【解决方案10】:

                  聚集索引物理存储在表中。这意味着它们是最快的,每个表只能有一个聚集索引。

                  非聚集索引是单独存储的,您可以拥有任意数量的索引。

                  最好的选择是将聚集索引设置在最常用的唯一列上,通常是 PK。除非有非常令人信服的理由——想不出一个,但嘿,它可能就在那里——因为不这样做会出现。

                  【讨论】:

                  • 您能否详细说明“我们的表中应该始终有一个聚集索引”?没有详细说明,由于 always 这个词,该陈述完全是错误的
                  • 你说得对 Pacerier,不应该轻易使用绝对陈述。虽然我不知道您不应该有一个精心选择的聚集索引的单一情况,但这种情况可能存在,所以我将我的答案更改为更通用的版本。
                  【解决方案11】:

                  聚集索引本质上是索引列中数据的排序副本。

                  聚集索引的主要优势在于,当您的查询(查找)在索引中定位数据时,无需额外的 IO 即可检索该数据。

                  维护聚集索引的开销,尤其是在频繁更新的表中,可能会导致性能下降,因此最好创建非聚集索引。

                  【讨论】:

                    【解决方案12】:

                    聚集索引对磁盘上的数据进行物理排序。这意味着索引不需要额外的数据,但只能有一个聚集索引(显然)。使用聚集索引访问数据是最快的。

                    所有其他索引必须是非聚集的。非聚集索引具有来自索引列的数据的副本,这些数据与指向实际数据行的指针一起保持有序(如果存在则指向聚集索引的指针)。这意味着通过非聚集索引访问数据必须经过额外的间接层。但是,如果您只选择索引列中可用的数据,您可以直接从重复的索引数据中取回数据(这就是为什么最好只选择您需要的列而不使用 *)

                    【讨论】:

                    • '但是,如果您仅选择索引列中可用的数据,您可以直接从重复的索引数据中获取数据' - 是的,这是首选聚集索引启发式的重要例外。我猜在这种情况下,您基本上有一个聚集索引,但您正在查询的表中的数据较少,因此可能可以更快地从磁盘读取。
                    【解决方案13】:

                    聚集索引实际上描述了记录在磁盘上的物理存储顺序,因此您只能拥有一个。

                    非聚集索引定义的逻辑顺序与磁盘上的物理顺序不匹配。

                    【讨论】:

                      猜你喜欢
                      • 2011-05-21
                      • 1970-01-01
                      • 2013-08-07
                      • 2011-04-23
                      • 1970-01-01
                      • 2011-07-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多