La conversion de type dans l'expression peut affecter «CardinalityEstimate» dans le choix du plan de requête?

10

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?

Iain Samuel McLean Elder
la source
2
Le COLLATE Latin1_General_BIN2rend l'expression checks.nameindiscutable. 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é.
Martin Smith
2
En supposant que le binaire COLLATEest seulement là pour faire le travail d'expression de gamme correctement , vous pouvez remplacer N'[0-9A-F]')avec N'[0123456789ABCDEF]'et laissez tomber leCOLLATE Latin1_General_BIN2
Martin Smith

Réponses:

16

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?

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 REPLACEpourrait être remplacé par:

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

(Cette réponse est un résumé des commentaires à la question.)

Paul White 9
la source