web-dev-qa-db-ja.com

式の型変換は、クエリプランの選択で「CardinalityEstimate」に影響を与える可能性がありますか?

パーティションビューに履歴データを格納するアーカイブデータベースを維持しています。パーティション化列は日時です。ビューの下の各テーブルには、1か月分のデータが格納されます。

各テーブルのイベントを、datetime列のチェック制約で制約します。これにより、オプティマイザは、イベントの日時列でフィルタリングするクエリを検索するテーブルを制限できます。

チェック制約の名前はSQL Serverによって生成されているため、名前を確認しても何を行うかを知ることは困難です。

制約名を「CK_TableName_Partition」の形式にしたい。

このクエリを使用し、sql_text列からデータをコピーして、名前変更スクリプトを生成できます。 WHERE句は、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;

出力は次のようになります。

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

クエリの結果は正しいようで、サーバーはそれをすばやく実行します。

ただし、実行プランのルートノードには警告があります。

式の型変換(CONVERT_IMPLICIT(nvarchar(128)、[o]。[name]、0))は、クエリプランの選択で "CardinalityEstimate"に影響する可能性があります

これはどういう意味ですか?そのような複雑なフィルターはオプティマイザーを混乱させますか?気になりますか?

クエリの結果は正しいようで、サーバーはそれをすばやく実行します。

ただし、実行プランのルートノードには警告があります。

式の型変換(CONVERT_IMPLICIT(nvarchar(128)、[o]。[name]、0))は、クエリプランの選択で "CardinalityEstimate"に影響する可能性があります

これはどういう意味ですか?そのような複雑なフィルターはオプティマイザーを混乱させますか?気になりますか?

警告は情報提供です。クエリの実行速度が遅い場合、またはカーディナリティの推定値が正しくないことに気付いた場合、警告により、考えられる原因を探す場所に関する情報が提供されます。

警告は、照合順序の変更に使用される暗黙的な変換によってトリガーされます。正しい結果を得るための最も簡単な方法が照合順序の使用である場合は、そのままにしておいてもかまいません。あるいは、なぜそれが必要なのかについてさらに説明すると、誰かがあなたに助言します。

余談ですが、REPLACEは次のように置き換えることができます。

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

(この回答は、質問に対するコメントの要約です。)

16
Paul White 9