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?
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
COLLATE Latin1_General_BIN2
rende l'espressione su nonchecks.name
targetizzabile. Tuttavia, per la tua specifica query non sei sicuro di quanto possa fare la differenza nelle stime della cardinalità.