Je gère une base de données d'archives qui stocke les données historiques dans des vues partitionnées. La colonne de partitionnement est un datetime. Chaque table sous la vue stocke un mois de données.
Nous contraignons les événements sur chaque table avec une contrainte de vérification sur la colonne datetime. Cela permet à l'optimiseur de limiter les tables qui sont recherchées pour les requêtes qui filtrent sur la colonne datetime de l'événement.
Les noms des contraintes de vérification ont été générés par SQL Server, il est donc difficile de savoir ce qu'ils font en regardant leur nom.
Je veux que les noms de contraintes aient la forme «CK_TableName_Partition».
Je peux générer un script de renommage en utilisant cette requête et en copiant les données de la colonne sql_text. La clause WHERE correspond aux contraintes de vérification dont les noms semblent avoir été générés par 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;
La sortie ressemble à ceci:
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';
Le résultat de la requête semble être correct et le serveur l'exécute rapidement.
Mais le nœud racine du plan d'exécution a un avertissement:
La conversion de type dans l'expression (CONVERT_IMPLICIT (nvarchar (128), [o]. [Nom], 0)) peut affecter "CardinalityEstimate" dans le choix du plan de requête
Qu'est-ce que cela signifie dans ce contexte? Un filtre aussi complexe confond-il l'optimiseur? Est-ce quelque chose qui devrait m'inquiéter?
la source
COLLATE Latin1_General_BIN2
rend l'expressionchecks.name
indiscutable. Pour votre requête spécifique, vous ne savez pas combien, le cas échéant, cela fera une différence dans les estimations de cardinalité.COLLATE
est seulement là pour faire le travail d'expression de gamme correctement , vous pouvez remplacerN'[0-9A-F]')
avecN'[0123456789ABCDEF]'
et laissez tomber leCOLLATE Latin1_General_BIN2
Réponses:
L'avertissement est informatif. Si votre requête s'exécute lentement ou si vous remarquez que les estimations de cardinalité sont incorrectes, l'avertissement vous donne des informations sur la recherche d'une cause possible.
L'avertissement est déclenché par la conversion implicite utilisée pour la modification du classement. Si l'utilisation du classement est le moyen le plus simple d'obtenir des résultats corrects, n'hésitez pas à le laisser tel quel. Alternativement, si vous expliquez davantage pourquoi il est nécessaire, quelqu'un vous conseillera.
Soit dit en passant, le
REPLACE
pourrait être remplacé par:(Cette réponse est un résumé des commentaires à la question.)
la source