我已经读过 varchar 字段应该作为列放在数据库表的末尾 - 至少在 MySQL 中。原因是 varchar 字段具有可变长度,它可能会减慢查询速度。我的问题:这是否适用于 MSSQL 2012?我是否应该将表格设计为在每个数据库行的末尾包含每个文本数据?
2 回答
与数据库设计(实体、属性和关系)、事务设计和查询设计的性能影响相比,表中列的顺序对性能的影响非常小。
要判断差异是否不可忽略,您确实需要设置一些测试并比较结果。
通常,我将主键作为第一列,然后是外键,然后是自然键和经常访问的列。我通常将较长的字符串放在行尾。但这不一定是性能优化,它是我为方便起见而使用的一种风格偏好。
当行中的大量列可以为空并且这些列中的大多数包含 NULL 时,列的顺序会对 SQL Server 中的行大小产生影响。SQL Server(如 Oracle)进行了优化,其中没有为在行的末尾包含 NULL 值的列保留空间。为行中的每一列保留一些空间,直到行中的最后一个非 NULL 值。
从中得出的结论是,如果您有很多可为空的列,则您希望在最常为 NULL 的列之前最常不为 NULL 的列。
注意:请记住,SQL Server 首先根据列是固定长度还是可变长度来对表中的列进行排序。首先存储所有固定长度列,然后存储所有可变长度列。在这些列集(固定和可变)中,列按定义的顺序存储。
在创建索引时,列顺序确实很重要。
索引键在索引的第一列上排序,然后在前一列的每个值内的下一列上进行子排序。复合索引中的第一列通常称为索引的前沿。例如,考虑这个表:
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)
将使这两个查询受益。但是索引 on(c1, c2)
并不合适,因为它最初会对数据进行排序c1
,而第一SELECT
条语句需要对数据进行排序c2
。
来源:SQL Server 2008 查询性能调优提炼