La conversione del tipo nell'espressione può influire su "CardinalityEstimate" nella scelta del piano di query?


10

Mantengo un database di archivio che memorizza i dati storici in viste partizionate. La colonna di partizionamento è un datetime. Ogni tabella sotto la vista memorizza un mese di dati.

Vincoliamo gli eventi su ogni tabella con un vincolo check sulla colonna datetime. Ciò consente all'ottimizzatore di limitare le tabelle cercate per le query che filtrano nella colonna datetime dell'evento.

I nomi dei vincoli di controllo sono stati generati da SQL Server, quindi è difficile sapere cosa fanno osservando il loro nome.

Voglio che i nomi dei vincoli abbiano la forma "CK_TableName_Partition".

Posso generare uno script di rinomina usando questa query e copiando i dati dalla colonna sql_text. La clausola WHERE corrisponde ai vincoli di controllo i cui nomi sembrano essere stati generati da 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;

L'output è simile al seguente:

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

Il risultato della query sembra essere corretto e il server la esegue rapidamente.

Ma il nodo radice del piano di esecuzione ha un avviso:

La conversione del tipo nell'espressione (CONVERT_IMPLICIT (nvarchar (128), [o]. [Nome], 0)) può influire su "CardinalityEstimate" nella scelta del piano di query

Cosa significa questo in questo contesto? Un filtro così complesso confonde l'ottimizzatore? È qualcosa di cui dovrei preoccuparmi?


2
Il COLLATE Latin1_General_BIN2rende l'espressione su non checks.nametargetizzabile. Tuttavia, per la tua specifica query non sei sicuro di quanto possa fare la differenza nelle stime della cardinalità.
Martin Smith,

2
Supponendo che il binario COLLATEè lì solo per far funzionare correttamente espressione di intervallo si potrebbe sostituire N'[0-9A-F]')con N'[0123456789ABCDEF]'e lascia cadere laCOLLATE Latin1_General_BIN2
Martin Smith

Risposte:


16

Il risultato della query sembra essere corretto e il server la esegue rapidamente.

Ma il nodo radice del piano di esecuzione ha un avviso:

La conversione del tipo nell'espressione (CONVERT_IMPLICIT (nvarchar (128), [o]. [Nome], 0)) può influire su "CardinalityEstimate" nella scelta del piano di query

Cosa significa questo in questo contesto? Un filtro così complesso confonde l'ottimizzatore? È qualcosa di cui dovrei preoccuparmi?

L'avvertimento è informativo. Se la tua query viene eseguita lentamente o noti che le stime sulla cardinalità non sono corrette, l'avviso ti fornirà informazioni su dove cercare una possibile causa.

L'avviso viene attivato dalla conversione implicita utilizzata per la modifica delle regole di confronto. Se utilizzare la raccolta è il modo più semplice per ottenere risultati corretti, sentiti libero di lasciarlo così com'è. In alternativa, se spieghi di più sul perché è necessario, qualcuno ti consiglierà.

A parte, REPLACEpotrebbe essere sostituito con:

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

(Questa risposta è un riepilogo dei commenti alla domanda.)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.