sql-server – 更改数据库默认排序规则时的Latin1_General_BIN性能影响

前端之家收集整理的这篇文章主要介绍了sql-server – 更改数据库默认排序规则时的Latin1_General_BIN性能影响前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我已将数据库排序规则设置为Latin1_General_BIN,以使字符串比较区分大小写.这会对性能产生影响吗?它会对数据库中的DML或DDL操作产生任何影响吗?数据库已存在,其中包含表.

解决方法

Collations in SQL Server确定匹配和排序字符数据的规则.通常,您将首先根据比较语义和数据使用者所需的排序顺序选择排序规则.

人类通常不会发现binary collations产生他们期望的分类和比较行为.因此,尽管这些提供了最佳性能(特别是纯代码点BIN2版本),但大多数实现都不使用它们.

接下来是原始性能术语(但仅适用于非Unicode字符串)是向后兼容性SQL collations.使用Unicode数据时,这些排序规则使用Windows collation,具有相同的性能特征.这里有一些微妙的陷阱,所以你需要有充分的理由来选择sql排序规则(除非在美国系统上工作,它仍然是默认设置).

由于复杂的Unicode比较和排序规则,Windows排序规则通常是最慢的.尽管如此,这些提供与sql Server中的Windows完全兼容,并定期维护以跟上Unicode标准的变化.对于包含Unicode数据的现代用途,通常建议使用Windows排序规则.

TL; DR

如果你想要的只是区分大小写的比较和排序语义,你应该选择_CS_(用于区分大小写)变体,无论哪个基础排序规则为用户的语言和文化提供预期的行为.例如,这两个都是区分大小写的排序规则:

-- Latin1-General,case-sensitive,accent-sensitive
Latin1_General_CS_AS 

-- Latin1-General,accent-sensitive for Unicode Data,-- sql Server Sort Order 51 on Code Page 1252 for non-Unicode Data
sql_Latin1_General_CP1_CS_AS

您可以使用sys.fn_helpcollations查看这些定义

例子

除了整理之外,四个表完全相同;一个二进制文件,一个区分大小写,一个不区分大小写,一个sql区分大小写:

CREATE TABLE #Example_BIN
(
    string nvarchar(50) 
        COLLATE Latin1_General_BIN
        NOT NULL
);

CREATE TABLE #Example_CS
(
    string nvarchar(50) 
        COLLATE Latin1_General_CS_AI
        NOT NULL
);

CREATE TABLE #Example_CI
(
    string nvarchar(50) 
        COLLATE Latin1_General_CI_AI
        NOT NULL
);

CREATE TABLE #Example_sql
(
    string varchar(50) -- Note varchar
        COLLATE sql_Latin1_General_CP1_CS_AS
        NOT NULL
);

每个表的相同样本数据:

INSERT #Example_BIN
    (string)
VALUES
    (N'A'),(N'a'),(N'B'),(N'b'),(N'C'),(N'c');

INSERT #Example_CS
SELECT EB.string 
FROM #Example_BIN AS EB;

INSERT #Example_CI
SELECT EB.string 
FROM #Example_BIN AS EB;

INSERT #Example_sql
SELECT EB.string 
FROM #Example_BIN AS EB;

现在我们要查找大于’a’的字符串:

SELECT EB.string AS BIN
FROM #Example_BIN AS EB
WHERE EB.string > N'a'
ORDER BY EB.string;

SELECT EC.string AS CS
FROM #Example_CS AS EC
WHERE EC.string > N'a'
ORDER BY EC.string;

SELECT EC2.string AS CI
FROM #Example_CI AS EC2
WHERE EC2.string > N'a'
ORDER BY EC2.string;

SELECT ES.string AS sql
FROM #Example_sql AS ES
WHERE ES.string > 'a' -- not Unicode
ORDER BY ES.string;

结果:

╔═════╗
║ BIN ║
╠═════╣
║ b   ║
║ c   ║
╚═════╝

╔════╗
║ CS ║
╠════╣
║ A  ║
║ b  ║
║ B  ║
║ c  ║
║ C  ║
╚════╝

╔════╗
║ CI ║
╠════╣
║ B  ║
║ b  ║
║ C  ║
║ c  ║
╚════╝

╔═════╗
║ sql ║
╠═════╣
║ B   ║
║ b   ║
║ C   ║
║ c   ║
╚═════╝

最后…

但请注意,如果我们将Unicode文字sql排序规则一起使用,则隐式转换规则会导致Windows排序规则比较:

SELECT ES.string AS sql
FROM #Example_sql AS ES
WHERE ES.string > N'a'
ORDER BY ES.string;

…并且sql排序规则结果发生了变化:

╔═════╗
║ sql ║
╠═════╣
║ A   ║
║ B   ║
║ b   ║
║ C   ║
║ c   ║
╚═════╝

猜你在找的MsSQL相关文章