如何解决SQL Server 中的聚集索引:列在架构中的第一个有什么优势?
我有一个包含列 (CustomerID,A,ProductID,C,OtherID
) 的表,并且我在 (OtherID,CustomerID,ProductID
) 上有一个聚集键。
该列顺序是否有性能影响(在表中,而不是索引?)或者将键列重新排序为表的前三列是否有隐藏的优势:(OtherID,C)
看起来这应该不是什么大问题,但实现可能会有隐藏的性能成本。
(我一直在寻找我们遇到的性能问题的原因,这只是其中一个“它不应该,但也许它可能是一个问题.. .”有点猜测。)
解决方法
我不会假设我们在这里讨论的是哪种类型的聚集索引,所以我将尝试涵盖所有基础知识。我不得不说,逻辑上,表中列的序数位置相对于它们在聚集索引中的序数位置的影响(性能或其他)是无关紧要的(除非有人在那里有什么东西可以证明我是错的)。
行存储
请记住,您的表数据和行存储聚集索引最终会成为独立的逻辑结构。 Per Microsoft regarding the clustered rowstore index architecture:
索引被组织为 B 树。索引 B 树中的每一页称为索引节点。 B 树的顶部节点称为根节点。索引中的底部节点称为叶节点。根节点和叶节点之间的任何索引级别统称为中间级别。在聚集索引中,叶节点包含基础表的数据页。根级节点和中间级节点包含保存索引行的索引页。
因此,当我们谈论聚集索引和表数据的物理存储时,我们可以将它们视为单独的结构。从同一链接查看此图像:
这三个级别至少有一个共同点。它们都存储按聚集索引值逻辑排序的值(或多或少)。无论表结构中列的顺序位置如何,表数据的叶页都将按聚集索引中的列/值进行逻辑排序。这也适用于您的中间页,它们代表您的聚集索引值的存储。
综上所述,聚集索引中列的序数位置实际上决定了中间级页和叶页的逻辑排序方式,因此表语句中这些列的序数位置实际上没有由于它们包含在您的聚集索引中,因此会影响它们的存储顺序。
列存储
关于聚集列存储索引,我会再次说它没有影响,但出于不同(且更简单)的原因。列存储索引将列值分解为单独的逻辑结构,这些逻辑结构通过它们的序数位置彼此没有关系。因此,无论列在表中的序号位置如何,当您从列中查询值时,您都是在查询表示该列值的单独物理结构(此处为了简单起见忽略了增量存储)。类似地,当您查询多个列的值时,您是在查询分别代表每列值的每个单独的逻辑结构。
这就是为什么在 creating a clustered columnstore index 时您甚至无法指定列列表的原因。列存储索引本身中列的序数位置没有影响,所以我想这些列在表本身中的序数位置(或两者之间的任何关系)也没有影响。
堆
最后,如果其他人问,即使表存储为堆,我仍然认为表中列的序数位置对任何查询性能没有影响。在幕后,堆仍然由一种聚集索引结构存储和引用(我相信它仍然会被这样描述)。
行存储是在逻辑上组织为包含行和列的表的数据,然后以行数据格式物理存储。这是存储关系表数据(例如堆或聚集 B 树索引)的传统方式。
所以堆仍然以有序的方式存储,就像使用聚集索引创建的任何其他表一样,但主要区别在于它们排序的值只是为了标识行而创建的非业务用途值。 As described by Microsoft:
如果表是堆,这意味着它没有聚集索引,行定位器是指向行的指针。指针是根据文件标识符 (ID)、页码和页上的行号构建的。整个指针称为行 ID (RID)。
这个 RID 不是您通常会用作查询谓词的东西,这是主要缺点(因为要查询数据,对吗?)。但无论如何,这些列在您的表中的顺序位置仍然对它们的实际逻辑排序/存储方式没有影响,因此我无法想象它会影响您的查询性能。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。