列排序是不是会影响 Microsoft SQL Server 2012 中的性能?
Posted
技术标签:
【中文标题】列排序是不是会影响 Microsoft SQL Server 2012 中的性能?【英文标题】:Does column ordering affects performance in Microsoft SQL Server 2012?列排序是否会影响 Microsoft SQL Server 2012 中的性能? 【发布时间】:2012-08-29 14:26:54 【问题描述】:我已经读到 varchar 字段应该作为列放在数据库表的末尾 - 至少在 mysql 中。原因是 varchar 字段具有可变长度,它可能会减慢查询速度。 我的问题:这是否适用于 MSSQL 2012? 我是否应该将表格设计为在每个数据库行的末尾包含每个文本数据?
【问题讨论】:
我不相信这对 MySQL 来说是正确的。是的,它是可变宽度 - 但它在行中的位置有什么不同? Is there any reason to worry about the column order in a table? 的可能副本另请参阅 @Quassnoi's blog article 关于此主题。 的想法是该行可能会在某个时候更新,从而导致数据位于磁盘上其他位置的“链式行”,从而导致更多的磁盘 io... 可能很小,但可能会造成一些有时差异很小 @Randy 我不相信 MySQL 有链式行这样的东西。相反,旧行无效,更新的行写在末尾(或空闲位置)。 myisam 和 innodb 的做法不同,但我不相信任何一个都有链式行。然而,链接答案中必须寻找可变长度列的问题很有趣。 【参考方案1】:在创建索引时,列顺序确实很重要。
索引键在索引的第一列上排序,然后在前一列的每个值内的下一列上进行子排序。复合索引中的第一列通常被称为索引的前沿。例如,考虑这个表:
c1 c2 1 1 2 1 3 1 1 2 2 2 3 2如果在
(c1, c2)
列上创建了复合索引,则索引将按下表所示排序:c1 c2 1 1 1 2 2 1 2 2 3 1 3 2如上表所示,数据按复合索引的第一列(
c1
)排序。在第一列的每个值内,数据在第二列 (c2
) 上进一步排序。因此,复合索引中的列顺序是索引有效性的一个重要因素。您可以通过考虑以下几点来了解这一点:
列唯一性 列宽 列数据类型
SELECT * FROM t1 WHERE c2 = 12
SELECT * FROM t1 WHERE c2 = 12 AND c1 = 11
(c2, c1)
上的索引将使这两个查询受益。但是(c1, c2)
上的索引不合适,因为它最初会在c1
上对数据进行排序,而第一个SELECT
语句需要在c2
上对数据进行排序。
来源:SQL Server 2008 查询性能调优提炼
【讨论】:
您的意思是:“(c2, c1) 上的索引将使两个查询都受益”而不是“(c1, c2) 上的索引将使两个查询受益”? @Zsolt 确实我做到了!谢谢你抓住那个。我已经编辑了我的答案。【参考方案2】:与数据库设计(实体、属性和关系)、事务设计和查询设计对性能的影响相比,表中列的顺序对性能的影响非常小。
要判断差异是否不可忽略,您确实需要设置一些测试并比较结果。
通常,我将主键作为第一列,然后是外键,然后是自然键和经常访问的列。我通常将较长的字符串放在行尾。但这不一定是性能优化,而是我为了方便而使用的样式偏好。
当行中的大量列可以为空并且这些列中的大多数包含 NULL 时,列的顺序会对 SQL Server 中的行大小产生影响。 SQL Server(如 Oracle)进行了优化,其中没有为在行的末尾包含 NULL 值的列保留空间。为行中的每一列保留一些空间,直到行中的最后一个非 NULL 值。
从中得出的结论是,如果您有很多可以为空的列,您希望在最常为 NULL 的列之前最常不为 NULL 的列。
注意:请记住,SQL Server 首先根据列是固定长度还是可变长度来对表中的列进行排序。首先存储所有固定长度列,然后存储所有可变长度列。在这些列集(固定和可变)中,列按定义的顺序存储。
【讨论】:
以上是关于列排序是不是会影响 Microsoft SQL Server 2012 中的性能?的主要内容,如果未能解决你的问题,请参考以下文章