Eu mantenho um banco de dados de arquivo que armazena dados históricos em exibições particionadas. A coluna de particionamento é um datetime. Cada tabela sob a exibição armazena um mês de dados.
Restringimos os eventos em cada tabela com uma restrição de verificação na coluna de data e hora. Isso permite que o otimizador limite as tabelas que são pesquisadas para consultas que filtram na coluna de data e hora do evento.
Os nomes das restrições de verificação foram gerados pelo SQL Server, portanto, é difícil saber o que elas fazem olhando seus nomes.
Eu quero que os nomes das restrições tenham o formato 'CK_TableName_Partition'.
Posso gerar um script de renomeação usando esta consulta e copiando dados da coluna sql_text. A cláusula WHERE corresponde a restrições de verificação cujos nomes parecem ter sido 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 se parece com isto:
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 tem um aviso:
A conversão de tipo na expressão (CONVERT_IMPLICIT(nvarchar(128),[o].[nome],0)) pode afetar "CardinalityEstimate" na escolha do plano de consulta
O que isso significa neste contexto? Um filtro tão complexo está confundindo o otimizador? É algo que eu deveria me preocupar?
O aviso é informativo. Se sua consulta for executada lentamente ou se 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 do agrupamento. Se usar o agrupamento for a maneira mais fácil de obter resultados corretos, fique à vontade para deixá-lo como está. Alternativamente, se você explicar mais sobre por que é necessário, alguém irá aconselhá-lo.
Como um aparte, o
REPLACE
poderia ser substituído por:(Esta resposta é um resumo dos comentários à pergunta.)