【问题标题】: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 来说是正确的。是的,它是可变宽度 - 但它在行中的位置有什么不同?
  • 的想法是该行可能会在某个时候更新,从而导致数据位于磁盘上其他位置的“链式行”,从而导致更多的磁盘 io... 可能很小,但可能会造成一些有时差异很小
  • @Randy 我不相信 MySQL 有链式行这样的东西。相反,旧行无效,更新的行写在末尾(或空闲位置)。 myisam 和 innodb 的做法不同,但我不相信任何一个都有链式行。然而,链接答案中必须寻找可变长度列的问题很有趣。

标签: mysql sql-server database database-design varchar


【解决方案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 首先根据列是固定长度还是可变长度来对表中的列进行排序。首先存储所有固定长度列,然后存储所有可变长度列。在这些列集(固定和可变)中,列按定义的顺序存储。

【讨论】:

    猜你喜欢
    • 2016-03-10
    • 2019-05-13
    • 1970-01-01
    • 2011-01-20
    • 2017-02-12
    • 1970-01-01
    • 2016-03-07
    • 2015-04-17
    相关资源
    最近更新 更多