sql-server – 旧的归类类型会影响数据库性能吗?

在我的项目中,我们使用SQL_1xCompat_CP850_CI_AS作为SQL Server实例和应用程序数据库的排序规则设置.据我所知,这是一个非常旧的排序规则,仅为了向后兼容目的而仍然支持.我想知道这种“旧”排序规则类型的使用是否会影响整体SQL Server性能?

另外,SQL_1xCompat_CP850_CI_AS和SQL_Latin1_General_Pref_Cp850_CI_AScollat​​ion之间有什么区别吗?
MSDN上的描述看起来非常相似:enter image description here
两者都是CI_AS_KI_WI,使用代码页850,并具有相同的排序顺序名称nocase34.850.
如果我们将校对设置更改为SQL_Latin1_General_Pref_Cp850_CI_AS,我们是否会有任何好处?

最佳答案

I would like to know whether usage of such “old” collation type may impact overall SQL Server performance?

好吧,SQL_1xCompat_CP850_CI_AS和SQL_Latin1_General_Pref_CP850_CI_AS之间不应该有性能差异.两者都是旧的,简单的排序顺序列表,并没有考虑新的Windows排序规则(不以SQL_开头的那些)可以执行的任何Unicode语言规则(即使对于VARCHAR数据).

在典型情况下,使用较新的Windows Collat​​ions可能会略微降低性能,因为它们不仅仅是简单的列表,而且还可以使用Unicode语言规则.然而,由于功能更好,因此可能有任何性能下降是值得的.

性能提升的一个领域是使用SQL Server排序(一个以SQL_开头)将NVARCHAR数据与索引的VARCHAR列进行比较,因为需要进行转换.与NVARCHAR数据相比,使用Windows排序规则的索引VARCHAR列不会受到此命中.但这更像是技术性的注释,而不是大多数查询/场景应该是一个问题.

Is there any difference between SQL_1xCompat_CP850_CI_AS and SQL_Latin1_General_Pref_CP850_CI_AS?

如问题中提供的文档所示:是的.它们之间的排序顺序不同.这应该是唯一的区别,因为代码页和敏感度在它们之间是相同的.

请注意,该文档中存在两个错误(但这些差异并未改变这两个排序规则之间肯定存在两种不同排序顺序的事实):

> SQL_Latin1_General_Pref_CP850_CI_AS的排序顺序ID为43,而不是44
>排序顺序名称在两个列出的排序规则之间不能相同,因为它们是不同的ID(即使其中一个列出的ID不正确,正确的ID仍然不同).

要查看差异,请尝试以下测试:

建立

CREATE TABLE #CollationTest
(
  [Value] TINYINT NOT NULL PRIMARY KEY,
  [1xCompat] VARCHAR(10) COLLATE SQL_1xCompat_CP850_CI_AS NOT NULL,
  [Latin1] VARCHAR(10) COLLATE SQL_Latin1_General_CP850_CI_AS NOT NULL,
  [Latin1Pref] VARCHAR(10) COLLATE SQL_Latin1_General_Pref_CP850_CI_AS NOT NULL
);

;WITH nums AS
(
  SELECT TOP (256) (ROW_NUMBER() OVER (ORDER BY (SELECT 0)) - 1) AS [num]
  FROM   [master].[sys].[all_columns] ac
)
INSERT INTO #CollationTest ([Value], [1xCompat], [Latin1], [Latin1Pref])
  SELECT [num], CONVERT(VARBINARY(1), [num]), CONVERT(VARBINARY(1), [num]),
         CONVERT(VARBINARY(1), [num])
  FROM nums
  ORDER BY [num] ASC;

测试1:验证所有字符是否相同

SELECT * FROM #CollationTest;

测试2:比较它们之间的排序顺序

;WITH compat AS
(
  SELECT ct.[Value], ct.[1xCompat],
         ROW_NUMBER() OVER (ORDER BY ct.[1xCompat] ASC) AS [ord]
  FROM   #CollationTest ct
), lat AS
(
  SELECT ct.[Value], ct.[Latin1],
         ROW_NUMBER() OVER (ORDER BY ct.[Latin1] ASC) AS [ord]
  FROM   #CollationTest ct
), pref AS
(
  SELECT ct.[Value], ct.[Latin1Pref],
         ROW_NUMBER() OVER (ORDER BY ct.[Latin1Pref] ASC) AS [ord]
  FROM   #CollationTest ct
)
SELECT compat.[ord], compat.[1xCompat], lat.[Latin1], pref.[Latin1Pref]
FROM   compat
INNER JOIN lat
        ON lat.ord = compat.ord
INNER JOIN pref
        ON pref.ord = compat.ord
WHERE  compat.[Value] <> lat.[Value]
OR     compat.[Value] <> pref.[Value]
OR     lat.[Value] <> pref.[Value]
ORDER BY compat.[ord] ASC;

差异从行/值49开始,WHERE子句过滤掉它们都匹配的前48行(无聊的东西).

很明显,排序顺序存在很多差异.其中一个不同之处在于,使用SQL_1xCompat_CP850_CI_AS,52个非重音字符被组合在一起,大写字母始终是第一个,而重音字符不仅在其余字符中展开,而是大写和小写的版本同一封信甚至没有放在一起:

m, N, n, O

另一方面,使用SQL_Latin1_General_Pref_CP850_CI_AS,非重音和重音字符都在一起,按重音分组:

m, N, n, Ñ, ñ, O

Will we have any benefits if we will change our collation setting to SQL_Latin1_General_Pref_CP850_CI_AS?

最有可能唯一真正的好处可能就是长寿.我希望微软在某些时候摆脱SQL_1xCompat_CP850_CI_AS.

您应该测试移动到SQL_Latin1_General_Pref_CP850_CI_AS,如果排序顺序的差异不会对应用程序产生负面影响,那么可能是个好主意.

移动到Windows排序规则可能更好,但这涉及更多测试,因为还存在一些其他功能差异.不幸的是,使用以下内容我发现Windows Collat​​ions都没有使用Code Page 850:

SELECT *
FROM sys.fn_helpcollations()
WHERE  COLLATIONPROPERTY([name], 'CodePage') = 850;

因此,虽然仍然首选使用Windows排序规则,但从现有的Code Collat​​ion更改为更新的排序(最有可能使用Code Page 1252)是一项更大的测试工作.如果你有时间和资源,我会说它去,否则只是做你要求的改变:-).

转载注明原文:sql-server – 旧的归类类型会影响数据库性能吗? - 代码日志