En primer lugar, disculpas por una respuesta tan larga, ya que siento que todavía hay mucha confusión cuando la gente habla de términos como cotejo, orden de clasificación, página de códigos, etc.
De BOL :
Las intercalaciones en SQL Server proporcionan reglas de clasificación, mayúsculas y minúsculas y propiedades de sensibilidad de acento para sus datos . Las intercalaciones que se usan con los tipos de datos de caracteres como char y varchar dictan la página de códigos y los caracteres correspondientes que se pueden representar para ese tipo de datos. Ya sea que esté instalando una nueva instancia de SQL Server, restaurando una copia de seguridad de la base de datos o conectando el servidor a las bases de datos del cliente, es importante que comprenda los requisitos locales, el orden de clasificación y la sensibilidad a mayúsculas y minúsculas de los datos con los que trabajará. .
Esto significa que la Clasificación es muy importante ya que especifica reglas sobre cómo se ordenan y comparan las cadenas de caracteres de los datos.
Nota: Más información sobre PROPIEDAD DE COLECCIÓN
Ahora, primero entendamos las diferencias ......
Ejecutando debajo de 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
Los resultados serían:
Mirando los resultados anteriores, la única diferencia es el Orden de clasificación entre las 2 intercalaciones, pero eso no es cierto, lo que puede ver por qué de la siguiente manera:
Prueba 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
Resultados de la Prueba 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.
A partir de los resultados anteriores, podemos ver que no podemos comparar directamente los valores en columnas con diferentes intercalaciones, debe usar COLLATE
para comparar los valores de las columnas.
PRUEBA 2:
La principal diferencia es el rendimiento, como señala Erland Sommarskog en esta discusión sobre msdn .
--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')
--- Crear índices en ambas tablas
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)
--- Ejecuta las consultas
DBCC FREEPROCCACHE
GO
SELECT Comments FROM Table_Latin1_General_CI_AS WHERE Comments = 'kin_test1'
GO
--- Esto tendrá conversión IMPLÍCITA
--- Ejecuta las consultas
DBCC FREEPROCCACHE
GO
SELECT Comments FROM Table_SQL_Latin1_General_CP1_CI_AS WHERE Comments = 'kin_test1'
GO
--- Esto NO tendrá conversión IMPLÍCITA
La razón para la conversión implícita es porque, tengo mi base de datos y la clasificación del servidor como SQL_Latin1_General_CP1_CI_AS
y la tabla Table_Latin1_General_CI_AS tiene una columna Comentarios definidos como VARCHAR(50)
con COLLATE Latin1_General_CI_AS , por lo que durante la búsqueda, SQL Server tiene que hacer una conversión IMPLICIT.
Prueba 3:
Con la misma configuración, ahora compararemos las columnas varchar con los valores nvarchar para ver los cambios en los planes de ejecución.
- ejecuta la consulta
DBCC FREEPROCCACHE
GO
SELECT Comments FROM Table_Latin1_General_CI_AS WHERE Comments = (SELECT N'kin_test1' COLLATE Latin1_General_CI_AS)
GO
- ejecuta la consulta
DBCC FREEPROCCACHE
GO
SELECT Comments FROM Table_SQL_Latin1_General_CP1_CI_AS WHERE Comments = N'kin_test1'
GO
Tenga en cuenta que la primera consulta puede realizar la búsqueda de índice, pero tiene que hacer la conversión implícita, mientras que la segunda realiza una exploración de índice que resulta ineficiente en términos de rendimiento cuando explora tablas grandes.
Conclusión
- Todas las pruebas anteriores muestran que tener una clasificación correcta es muy importante para la instancia del servidor de la base de datos.
SQL_Latin1_General_CP1_CI_AS
es una recopilación de SQL con las reglas que le permiten ordenar los datos para unicode y no unicode son diferentes.
- La intercalación de SQL no podrá usar Index al comparar datos unicode y no unicode como se ve en las pruebas anteriores que al comparar los datos nvarchar con los datos varchar, escanea el índice y no busca.
Latin1_General_CI_AS
es una recopilación de Windows con las reglas que le permiten ordenar los datos para unicode y no unicode son los mismos.
- La intercalación de Windows todavía puede usar el índice (búsqueda de índice en el ejemplo anterior) al comparar datos unicode y no unicode, pero ve una ligera penalización de rendimiento.
- Recomiendo leer Erland Sommarskog respuesta + los elementos de conexión que ha señalado.
Esto me permitirá no tener problemas con las tablas #temp, pero ¿existen dificultades?
Vea mi respuesta arriba.
¿Perdería alguna funcionalidad o características de cualquier tipo al no utilizar una recopilación "actual" de SQL 2008?
Todo depende de la funcionalidad / características a las que se refiera. La clasificación es el almacenamiento y la clasificación de datos.
¿Qué pasa cuando nos mudamos (por ejemplo, en 2 años) de 2008 a SQL 2012? ¿Tendré problemas entonces? ¿En algún momento me vería obligado a ir a Latin1_General_CI_AS?
No puedo responder! Como las cosas pueden cambiar y siempre es bueno estar en línea con la sugerencia de Microsoft, debe comprender sus datos y las trampas que mencioné anteriormente. Consulte también esto y esto conecta elementos.
Leí que algunos scripts de DBA completan las filas de bases de datos completas, y luego ejecuto el script de inserción en la base de datos con la nueva recopilación.
Cuando desee cambiar la intercalación, estos scripts son útiles. Me he encontrado muchas veces cambiando la intercalación de bases de datos para que coincida con la intercalación del servidor y tengo algunos scripts que lo hacen bastante bien. Hazme saber si lo necesitas.
Referencias