列排序是不是会影响 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 中的性能?的主要内容,如果未能解决你的问题,请参考以下文章

SQL Jet 访问、插入列和排序依据

ORDER BY 子句是不是会减慢查询速度?

sql查询并新增一列,按条件排序后给这一列赋值,并满足条件按序列赋值

SQL优化,列列表上的条件会影响优化吗?

2.排序检索数据 ---SQL

SQL Server:按分组列求和并按另一列排序