Mantengo una base de datos de archivo que almacena datos históricos en vistas particionadas. La columna de partición es una fecha y hora. Cada tabla debajo de la vista almacena un mes de datos.
Restringimos los eventos en cada tabla con una restricción de verificación en la columna de fecha y hora. Esto permite al optimizador limitar las tablas en las que se buscan consultas que se filtran en la columna de fecha y hora del evento.
Los nombres de las restricciones de verificación fueron generados por SQL Server, por lo que es difícil saber qué hacen mirando su nombre.
Quiero que los nombres de las restricciones tengan la forma 'CK_TableName_Partition'.
Puedo generar un script de cambio de nombre usando esta consulta y copiando datos de la columna sql_text. La cláusula WHERE coincide con las restricciones de verificación cuyos nombres parecen haber sido generados por SQL Server:
SELECT
checks.name AS check_name,
tabs.name AS table_name,
skemas.name AS schema_name,
cols.name AS column_name,
N'
EXECUTE sys.sp_rename
@objname = N''' + skemas.name + N'.' + checks.name + N''',
@newname = N''CK_' + tabs.name + N'_Partition'',
@objtype = ''OBJECT'';' AS sql_text
FROM sys.check_constraints AS checks
INNER JOIN sys.tables AS tabs ON
tabs.object_id = checks.parent_object_id
INNER JOIN sys.schemas AS skemas ON
skemas.schema_id = tabs.schema_id
INNER JOIN sys.columns AS cols ON
tabs.object_id = cols.object_id AND
cols.column_id = checks.parent_column_id
WHERE checks.name LIKE (
N'CK__' + SUBSTRING(tabs.name, 1, 9) +
N'__' + SUBSTRING(cols.name, 1, 5) +
N'__' + REPLACE(N'xxxxxxxx', N'x', N'[0-9A-F]') COLLATE Latin1_General_BIN2
)
ORDER BY table_name;
El resultado se ve así:
check_name table_name schema_name column_name sql_text
CK__tbAcquisi__Acqui__5C4299A5 tbAcquisitions_201301 Archive AcquisitionDT EXECUTE sys.sp_rename @objname = N'Archive.CK__tbAcquisi__Acqui__5C4299A5', @newname = N'CK_tbAcquisitions_201301_Partition', @objtype = 'OBJECT';
CK__tbAcquisi__Acqui__76026BA8 tbAcquisitions_201302 Archive AcquisitionDT EXECUTE sys.sp_rename @objname = N'Archive.CK__tbAcquisi__Acqui__76026BA8', @newname = N'CK_tbAcquisitions_201302_Partition', @objtype = 'OBJECT';
CK__tbAcquisi__Acqui__7D6E8346 tbAcquisitions_201303 Archive AcquisitionDT EXECUTE sys.sp_rename @objname = N'Archive.CK__tbAcquisi__Acqui__7D6E8346', @newname = N'CK_tbAcquisitions_201303_Partition', @objtype = 'OBJECT';
...
CK__tbRequest__Reque__60132A89 tbRequests_201301 Archive RequestDT EXECUTE sys.sp_rename @objname = N'Archive.CK__tbRequest__Reque__60132A89', @newname = N'CK_tbRequests_201301_Partition', @objtype = 'OBJECT';
CK__tbRequest__Reque__1392CE8F tbRequests_201302 Archive RequestDT EXECUTE sys.sp_rename @objname = N'Archive.CK__tbRequest__Reque__1392CE8F', @newname = N'CK_tbRequests_201302_Partition', @objtype = 'OBJECT';
CK__tbRequest__Reque__1AFEE62D tbRequests_201303 Archive RequestDT EXECUTE sys.sp_rename @objname = N'Archive.CK__tbRequest__Reque__1AFEE62D', @newname = N'CK_tbRequests_201303_Partition', @objtype = 'OBJECT';
El resultado de la consulta parece ser correcto y el servidor lo ejecuta rápidamente.
Pero el nodo raíz del plan de ejecución tiene una advertencia:
La conversión de tipos en la expresión (CONVERT_IMPLICIT (nvarchar (128), [o]. [Name], 0)) puede afectar a "CardinalityEstimate" en la elección del plan de consulta
¿Qué significa eso en este contexto? ¿Un filtro tan complejo confunde al optimizador? ¿Es algo de lo que debería preocuparme?
fuente
COLLATE Latin1_General_BIN2
hace que la expresión enchecks.name
inestable. Sin embargo, para su consulta específica, no estoy seguro de cuánto, si alguna diferencia, hará en las estimaciones de cardinalidad.COLLATE
sólo está allí para hacer el trabajo correctamente la expresión gama podría reemplazarN'[0-9A-F]')
conN'[0123456789ABCDEF]'
y soltar elCOLLATE Latin1_General_BIN2
Respuestas:
La advertencia es informativa. Si su consulta se realizó lentamente, o si notó que las estimaciones de cardinalidad eran incorrectas, la advertencia le daría información sobre dónde buscar una posible causa.
La advertencia se activa por la conversión implícita utilizada para el cambio de intercalación. Si usar la intercalación es la forma más fácil de obtener resultados correctos, siéntase libre de dejarla como está. Alternativamente, si explica más sobre por qué es necesario, alguien lo asesorará.
Como comentario, el
REPLACE
podría ser reemplazado por:(Esta respuesta es un resumen de los comentarios a la pregunta).
fuente