Sex*_*ast 4 index sql-server clustered-index nonclustered-index
我正在simple-talk上阅读有关索引的文章,其中写道
如果堆上有一个非聚集索引(作为主键),并且数据被插入到表中,则必须发生两次写入。一次写入用于插入行,一次写入用于更新非聚集索引。另一方面,如果一个表有一个聚集索引作为主键,插入只需要一次写入,而不是两次写入。这是因为聚集索引及其数据是一体的。因此,将行插入到以聚集索引为主键的表中比将相同的数据插入到以非聚集索引为主键的堆中要快。无论主键是否单调递增,都是如此。
是不是错了?聚集索引自然求助于 B+ 树,其中只有键存储在中间节点中(与 B 树不同,B 树存储整个记录。这就是为什么 B+ 树可以在单个页面中容纳更多键,导致其宽度庞大但高度较短),因此所有记录都存储在叶子页面中(页面本身通过链表进行逻辑排序,而每个页面中的数据进行物理排序)。因此,如果必须更新记录,例如必须将值 1 更新为 7,则更新是否需要同时应用于聚集索引顶部节点中的两个键(在某些情况下,这可能会导致重新整个结构的结构)和叶页中记录中的相应值?
更新:好的,我做了一些研究,发现除了初始树结构(其中一些值必须出现两次,例如节点中的键值),当插入新值时,它们正好适合叶页,而树被重组以适应这一点。但是,当插入 5 个值时,第 3 个值可能会导致第一个插入的值(当前仅占用叶级空间)级联,从而导致它被写入两次(一次在叶级,其他在叶级)指数水平)。当然,这种重写(虽然它们不会在插入时发生,但它们可以稍后发生)与每次插入到带有 NCI 的堆中时发生的两次写入相比要少得多,但是说没有重写也不是错吗?
我认为这里的问题是术语的不同。
通常所说的“写入次数”是对象访问的次数,而不是物理操作触及的页数。
在讨论中通常将其用作指标的原因是因为它是一个更“稳定”且更有意义的数字。当我们进入这里时,INSERT
即使是单行的语句所涉及的页数也取决于许多因素,因此在您自己的环境和情况之外,它不是一个非常有用的数量。
我会从文章引用中挑选的一件事是(强调我的):
一次写入用于插入行,一次写入用于更新非聚集索引。
这可能令人困惑。向基表插入一行将涉及对基表的插入,以及对每个非聚集索引的插入(忽略特殊索引功能),而不是更新。
因此,如果必须更新一条记录,例如必须将值 1 更新为 7,那么更新是否需要同时应用于聚集索引顶部节点中的两个键(在某些情况下,这可能会导致重新整个结构的结构)和叶页中记录中的相应值?
是的,假设更新的列在索引键中。但是,这仍然是单个对象访问,因此是“单个写入”。
归档时间: |
|
查看次数: |
387 次 |
最近记录: |