A conversão de tipo na expressão pode afetar "CardinalityEstimate" na escolha do plano de consulta?

10

Eu mantenho um banco de dados de arquivamento que armazena dados históricos em visualizações particionadas. A coluna de particionamento é uma data e hora. Cada tabela sob a visualização armazena um mês de dados.

Restringimos os eventos em cada tabela com uma restrição de verificação na coluna datetime. Isso permite que o otimizador limite as tabelas pesquisadas por consultas filtradas na coluna de data e hora do evento.

Os nomes das restrições de verificação foram gerados pelo SQL Server, por isso é difícil saber o que eles fazem observando o nome deles.

Desejo que os nomes das restrições tenham o formato 'CK_TableName_Partition'.

Eu posso gerar um script de renomeação usando esta consulta e copiando dados da coluna sql_text. A cláusula WHERE corresponde às restrições de verificação cujos nomes parecem que foram gerados pelo 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;

A saída é assim:

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';

O resultado da consulta parece estar correto e o servidor a executa rapidamente.

Mas o nó raiz do plano de execução possui um aviso:

A conversão de tipo na expressão (CONVERT_IMPLICIT (nvarchar (128), [o]. [Name], 0)) pode afetar "CardinalityEstimate" na escolha do plano de consulta

O que isso significa nesse contexto? Um filtro tão complexo está confundindo o otimizador? É algo que eu deveria me preocupar?

Iain Samuel McLean Elder
fonte
2
O COLLATE Latin1_General_BIN2torna a expressão checks.nameinsargável. Para sua consulta específica, não sei ao certo quanto, se houver alguma diferença, às estimativas de cardinalidade.
Martin Smith
2
Assumindo que o binário COLLATEé só lá para fazer o trabalho de expressão gama corretamente você poderia substituir N'[0-9A-F]')com N'[0123456789ABCDEF]'e soltar oCOLLATE Latin1_General_BIN2
Martin Smith

Respostas:

16

O resultado da consulta parece estar correto e o servidor a executa rapidamente.

Mas o nó raiz do plano de execução possui um aviso:

A conversão de tipo na expressão (CONVERT_IMPLICIT (nvarchar (128), [o]. [Name], 0)) pode afetar "CardinalityEstimate" na escolha do plano de consulta

O que isso significa nesse contexto? Um filtro tão complexo está confundindo o otimizador? É algo que eu deveria me preocupar?

O aviso é informativo. Se sua consulta for lenta, ou você perceber que as estimativas de cardinalidade estão incorretas, o aviso fornecerá informações sobre onde procurar uma possível causa.

O aviso é acionado pela conversão implícita usada para a alteração de agrupamento. Se usar o agrupamento é a maneira mais fácil de obter resultados corretos, fique à vontade para deixá-lo como está. Como alternativa, se você explicar mais sobre por que é necessário, alguém o aconselhará.

Como um aparte, o REPLACEpoderia ser substituído por:

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

(Esta resposta é um resumo dos comentários à pergunta.)

Paul White 9
fonte