Zunächst eine Entschuldigung für eine so lange Antwort, da ich das Gefühl habe, dass immer noch viel Verwirrung herrscht, wenn über Begriffe wie Kollatierung, Sortierreihenfolge, Codepage usw. gesprochen wird.
Von BOL :
Kollatierungen in SQL Server enthalten Sortierregeln, Groß- und Kleinschreibung und Eigenschaften für die Akzentempfindlichkeit Ihrer Daten . Kollatierungen, die mit Zeichendatentypen wie char und varchar verwendet werden, bestimmen die Codepage und die entsprechenden Zeichen, die für diesen Datentyp dargestellt werden können. Unabhängig davon, ob Sie eine neue Instanz von SQL Server installieren, eine Datenbanksicherung wiederherstellen oder den Server mit Client-Datenbanken verbinden, ist es wichtig, dass Sie die Anforderungen an das Gebietsschema, die Sortierreihenfolge sowie die Groß- und Kleinschreibung der Daten, mit denen Sie arbeiten, kennen .
Dies bedeutet, dass die Sortierung sehr wichtig ist, da sie Regeln für das Sortieren und Vergleichen von Zeichenfolgen der Daten festlegt.
Hinweis: Weitere Informationen zu COLLATIONPROPERTY
Jetzt lasst uns zuerst die Unterschiede verstehen ......
Laufen unter T-SQL:
SELECT *
FROM::fn_helpcollations()
WHERE NAME IN (
'SQL_Latin1_General_CP1_CI_AS'
,'Latin1_General_CI_AS'
)
GO
SELECT 'SQL_Latin1_General_CP1_CI_AS' AS 'Collation'
,COLLATIONPROPERTY('SQL_Latin1_General_CP1_CI_AS', 'CodePage') AS 'CodePage'
,COLLATIONPROPERTY('SQL_Latin1_General_CP1_CI_AS', 'LCID') AS 'LCID'
,COLLATIONPROPERTY('SQL_Latin1_General_CP1_CI_AS', 'ComparisonStyle') AS 'ComparisonStyle'
,COLLATIONPROPERTY('SQL_Latin1_General_CP1_CI_AS', 'Version') AS 'Version'
UNION ALL
SELECT 'Latin1_General_CI_AS' AS 'Collation'
,COLLATIONPROPERTY('Latin1_General_CI_AS', 'CodePage') AS 'CodePage'
,COLLATIONPROPERTY('Latin1_General_CI_AS', 'LCID') AS 'LCID'
,COLLATIONPROPERTY('Latin1_General_CI_AS', 'ComparisonStyle') AS 'ComparisonStyle'
,COLLATIONPROPERTY('Latin1_General_CI_AS', 'Version') AS 'Version'
GO
Die Ergebnisse wären:
![Bildbeschreibung hier eingeben](https://i.stack.imgur.com/VvtpW.jpg)
Wenn Sie sich die obigen Ergebnisse ansehen, ist der einzige Unterschied die Sortierreihenfolge zwischen den beiden Kollatierungen. Dies ist jedoch nicht der Fall. Hier sehen Sie, warum:
Test 1:
--Clean up previous query
IF OBJECT_ID('Table_Latin1_General_CI_AS') IS NOT NULL
DROP TABLE Table_Latin1_General_CI_AS;
IF OBJECT_ID('Table_SQL_Latin1_General_CP1_CI_AS') IS NOT NULL
DROP TABLE Table_SQL_Latin1_General_CP1_CI_AS;
-- Create a table using collation Latin1_General_CI_AS
CREATE TABLE Table_Latin1_General_CI_AS (
ID INT IDENTITY(1, 1)
,Comments VARCHAR(50) COLLATE Latin1_General_CI_AS
)
-- add some data to it
INSERT INTO Table_Latin1_General_CI_AS (Comments)
VALUES ('kin_test1')
INSERT INTO Table_Latin1_General_CI_AS (Comments)
VALUES ('Kin_Tester1')
-- Create second table using collation SQL_Latin1_General_CP1_CI_AS
CREATE TABLE Table_SQL_Latin1_General_CP1_CI_AS (
ID INT IDENTITY(1, 1)
,Comments VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS
)
-- add some data to it
INSERT INTO Table_SQL_Latin1_General_CP1_CI_AS (Comments)
VALUES ('kin_test1')
INSERT INTO Table_SQL_Latin1_General_CP1_CI_AS (Comments)
VALUES ('Kin_Tester1')
--Now try to join both tables
SELECT *
FROM Table_Latin1_General_CI_AS LG
INNER JOIN Table_SQL_Latin1_General_CP1_CI_AS SLG ON LG.Comments = SLG.Comments
GO
Ergebnisse von Test 1:
Msg 468, Level 16, State 9, Line 35
Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Latin1_General_CI_AS" in the equal to operation.
Aus den obigen Ergebnissen können wir ersehen, dass wir die Werte von Spalten mit unterschiedlichen Sortierungen nicht direkt vergleichen können. Sie müssen sie COLLATE
zum Vergleichen der Spaltenwerte verwenden.
TEST 2:
Der Hauptunterschied ist die Leistung, wie Erland Sommarskog bei dieser Diskussion über msdn betont .
--Clean up previous query
IF OBJECT_ID('Table_Latin1_General_CI_AS') IS NOT NULL
DROP TABLE Table_Latin1_General_CI_AS;
IF OBJECT_ID('Table_SQL_Latin1_General_CP1_CI_AS') IS NOT NULL
DROP TABLE Table_SQL_Latin1_General_CP1_CI_AS;
-- Create a table using collation Latin1_General_CI_AS
CREATE TABLE Table_Latin1_General_CI_AS (
ID INT IDENTITY(1, 1)
,Comments VARCHAR(50) COLLATE Latin1_General_CI_AS
)
-- add some data to it
INSERT INTO Table_Latin1_General_CI_AS (Comments)
VALUES ('kin_test1')
INSERT INTO Table_Latin1_General_CI_AS (Comments)
VALUES ('kin_tester1')
-- Create second table using collation SQL_Latin1_General_CP1_CI_AS
CREATE TABLE Table_SQL_Latin1_General_CP1_CI_AS (
ID INT IDENTITY(1, 1)
,Comments VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS
)
-- add some data to it
INSERT INTO Table_SQL_Latin1_General_CP1_CI_AS (Comments)
VALUES ('kin_test1')
INSERT INTO Table_SQL_Latin1_General_CP1_CI_AS (Comments)
VALUES ('kin_tester1')
--- Erstellen Sie Indizes für beide Tabellen
CREATE INDEX IX_LG_Comments ON Table_Latin1_General_CI_AS(Comments)
go
CREATE INDEX IX_SLG_Comments ON Table_SQL_Latin1_General_CP1_CI_AS(Comments)
--- Führen Sie die Abfragen aus
DBCC FREEPROCCACHE
GO
SELECT Comments FROM Table_Latin1_General_CI_AS WHERE Comments = 'kin_test1'
GO
--- Dies hat eine IMPLICIT-Konvertierung zur Folge
![Bildbeschreibung hier eingeben](https://i.stack.imgur.com/o6TsD.jpg)
--- Führen Sie die Abfragen aus
DBCC FREEPROCCACHE
GO
SELECT Comments FROM Table_SQL_Latin1_General_CP1_CI_AS WHERE Comments = 'kin_test1'
GO
--- Dies wird NICHT haben Implizite Konvertierung
![Bildbeschreibung hier eingeben](https://i.stack.imgur.com/Lhiu8.jpg)
Der Grund für die implizite Konvertierung liegt darin, dass ich meine Datenbank- und Server- Kollatierung sowohl als SQL_Latin1_General_CP1_CI_AS
als auch in der Tabelle Table_Latin1_General_CI_AS die Spalte Comments definiert habe, wie VARCHAR(50)
bei COLLATE Latin1_General_CI_AS , sodass SQL Server während der Suche eine IMPLICIT-Konvertierung durchführen muss.
Test 3:
Mit demselben Setup vergleichen wir jetzt die varchar-Spalten mit den nvarchar-Werten, um die Änderungen in den Ausführungsplänen zu sehen.
- Führen Sie die Abfrage aus
DBCC FREEPROCCACHE
GO
SELECT Comments FROM Table_Latin1_General_CI_AS WHERE Comments = (SELECT N'kin_test1' COLLATE Latin1_General_CI_AS)
GO
![Bildbeschreibung hier eingeben](https://i.stack.imgur.com/ZYsbJ.jpg)
- Führen Sie die Abfrage aus
DBCC FREEPROCCACHE
GO
SELECT Comments FROM Table_SQL_Latin1_General_CP1_CI_AS WHERE Comments = N'kin_test1'
GO
![Bildbeschreibung hier eingeben](https://i.stack.imgur.com/56BBC.jpg)
Beachten Sie, dass die erste Abfrage eine Indexsuche durchführen kann, jedoch eine implizite Konvertierung durchführen muss, während die zweite eine Indexsuche durchführt, die sich in Bezug auf die Leistung als ineffizient erweist, wenn große Tabellen durchsucht werden.
Fazit :
- Alle oben genannten Tests zeigen, dass die richtige Sortierung für Ihre Datenbankserverinstanz sehr wichtig ist.
SQL_Latin1_General_CP1_CI_AS
ist eine SQL-Kollatierung mit den Regeln, mit denen Sie Daten nach Unicode und Nicht-Unicode sortieren können.
- Die SQL-Kollatierung kann Index nicht verwenden, wenn Unicode- und Nicht-Unicode-Daten verglichen werden. Dies wurde in den obigen Tests gezeigt. Beim Vergleich von nvarchar-Daten mit varchar-Daten wird ein Index-Scan durchgeführt und keine Suche durchgeführt.
Latin1_General_CI_AS
ist eine Windows-Kollatierung mit den Regeln, mit denen Sie Daten sortieren können, die für Unicode und Nicht-Unicode gleich sind.
- Die Windows-Kollatierung kann beim Vergleich von Unicode- und Nicht-Unicode-Daten weiterhin den Index verwenden (Indexsuche im obigen Beispiel), es wird jedoch ein geringer Leistungsverlust angezeigt.
- Sehr zu empfehlen, die Antwort von Erland Sommarskog + die Verbindungselemente zu lesen, auf die er hingewiesen hat.
Dadurch kann ich keine Probleme mit # temporären Tabellen haben, aber gibt es Fallstricke?
Siehe meine Antwort oben.
Würde ich Funktionen oder Features jeglicher Art verlieren, wenn ich keine "aktuelle" Sortierung von SQL 2008 verwende?
Es hängt alles davon ab, auf welche Funktionen Sie sich beziehen. Beim Sortieren werden Daten gespeichert und sortiert.
Was ist, wenn wir (z. B. in 2 Jahren) von 2008 nach SQL 2012 wechseln? Habe ich dann Probleme? Würde ich irgendwann gezwungen sein, zu Latin1_General_CI_AS zu wechseln?
Kann nicht gutheißen! Da sich die Dinge ändern können und es immer gut ist, den Vorschlägen von Microsoft zu folgen, müssen Sie Ihre Daten und die oben erwähnten Fallstricke verstehen. Beachten Sie auch diese und diese Verbindungselemente.
Ich habe gelesen, dass ein DBA-Skript die Zeilen mit vollständigen Datenbanken vervollständigt und dann das Einfügeskript mit der neuen Kollatierung in der Datenbank ausführt.
Wenn Sie die Sortierung ändern möchten, sind solche Skripte hilfreich. Ich habe festgestellt, dass ich die Kollatierung von Datenbanken oft an die Kollatierung von Servern angeglichen habe, und ich habe einige Skripte, die das ziemlich ordentlich machen. Lass es mich wissen, wenn du es brauchst.
Verweise :