Sql-Server

更改數據庫預設排序規則時 Latin1_General_BIN 性能影響

  • October 6, 2015

我已將數據庫排序規則設置為Latin1_General_BIN,以使字元串比較區分大小寫。這會對性能產生影響嗎?會對數據庫中的 DML 或 DDL 操作有影響嗎?數據庫已經存在,其中包含表。

SQL Server 中的排序規則確定匹配和排序字元數據的規則。通常,您會首先根據數據使用者所需的比較語義和排序順序來選擇排序規則。

人類通常不會發現二進制排序規則會產生他們期望的排序和比較行為。因此,儘管這些提供了最佳性能(尤其是純程式碼點 BIN2 版本),但大多數實現不使用它們。

接下來在原始性能方面(但僅適用於非 Unicode 字元串)是向後兼容SQL 排序規則。處理 Unicode 數據時,這些排序規則使用Windows 排序規則,具有相同的性能特徵。這裡有一些微妙的陷阱,所以現在你需要有充分的理由選擇 SQL 排序規則(除非在美國系統上工作,它仍然是預設設置)。

由於復雜的 Unicode 比較和排序規則,Windows 排序規則通常是最慢的。然而,這些提供了與 SQL Server 中的 Windows 的完全兼容性,並且定期維護以跟上 Unicode 標準的變化。對於包含 Unicode 數據的現代用途,通常建議使用 Windows 排序規則。

TL; 博士

如果您想要的只是區分大小寫的比較和排序語義,您應該選擇_CS_為使用者語言和文化提供預期行為的任何基本排序規則的(區分大小寫)變體。例如,這些都是區分大小寫的排序規則:

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

-- Latin1-General, case-sensitive, 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_helpcollat​​ions查看這些定義

例子

除了排序規則外,四張完全相同的**表;**一個二進制,一個區分大小寫,一個不區分大小寫,一個 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   ║
╚═════╝

最後…

但請注意,如果我們在 SQL 排序規則中使用 Unicode 文字,則隱式轉換規則會導致 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   ║
╚═════╝

引用自:https://dba.stackexchange.com/questions/110911