¿La conversión de tipos en la expresión puede afectar a "CardinalityEstimate" en la elección del plan de consulta?

10

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?

Iain Samuel McLean Élder
fuente
2
El COLLATE Latin1_General_BIN2hace que la expresión en checks.nameinestable. Sin embargo, para su consulta específica, no estoy seguro de cuánto, si alguna diferencia, hará en las estimaciones de cardinalidad.
Martin Smith
2
Suponiendo que el binario COLLATEsólo está allí para hacer el trabajo correctamente la expresión gama podría reemplazar N'[0-9A-F]')con N'[0123456789ABCDEF]'y soltar elCOLLATE Latin1_General_BIN2
Martin Smith

Respuestas:

16

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?

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 REPLACEpodría ser reemplazado por:

REPLICATE(N'[0-9A-F]', 8);

(Esta respuesta es un resumen de los comentarios a la pregunta).

Paul White 9
fuente