SQL Server
A family of Microsoft relational database management and analysis systems for e-commerce, line-of-business, and data warehousing solutions.
11,005 questions
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
変更されたデータを CDC 経由で取り込むシステムを構築し運用を開始したところ、お客様環境で CPU 負荷が高いとのご指摘を受けました。
調査したところ次の処理で負荷が高いことが分かり対応方法を検討していますが、課題解決のアプローチとして正しいかどうかご教授いただけないでしょうか。
■処理内容
①キャプチャインスタンスで始端LSNを取得する
DECLARE @MinLsn BINARY(10) = sys.fn_cdc_get_min_lsn(@CaptureInstanceName)
②指定した日時以下で直近の始端LSNを取得する
DECLARE @FromLsn BINARY(10) = sys.fn_cdc_map_time_to_lsn(N'smallest greater than', CAST(@DateTime AS datetime))
③①と②の内、新しいほうを検索期間の始端とする
IF @FromLsn < @MinLsn
BEGIN
SET @FromLsn = @MinLsn
END
④始端LSNを日時に変換する
DECLARE @FromLsnTime DATETIME = sys.fn_cdc_map_lsn_to_time(@FromLsn)
⑤指定した秒数にオフセットを加算し、検索期間の終端を求める
DECLARE @ToLsn BINARY(10) = sys.fn_cdc_map_time_to_lsn(N'largest less than or equal', DATEADD(second, @Offset, @FromLsnTime))
⑥終端LSNを日時に変換する
※@ToLsnTime は次回実行時の②の「@DateTime」の引数に使用する
DECLARE @ToLsnTime DATETIME = sys.fn_cdc_map_lsn_to_time(@ToLsn)
⑦始端LSN、終端LSNをキーに変更データを取得する
SELECT
sys.fn_cdc_map_lsn_to_time(__$start_lsn) StartLsnTime
, __$start_lsn as StartLsn
, __$seqval as Seqval
, __$operation as Operation
, __$update_mask as UpdateMask
, *
FROM
cdc.fn_cdc_get_all_changes_{テーブル名}(@FromLsn, @ToLsn, 'all')
■問題となっていること
・sys.fn_cdc_map_time_to_lsn の実行時に CPU 負荷が高くなっていることが分かった。(上記②と⑤)
・お客様環境の cdc.lsn_time_mapping は約 1000 万件のデータが格納されており、sys.fn_cdc_map_time_to_lsn 実行時に全データを読み取っていることが分かった。
・上記①~⑦はリアルタイム性を維持するため、キャプチャインスタンスごとに4~8秒ごとに並列実行している。(同時実行数は4つまで)
※対象のキャプチャインスタンスは 19 テーブルあります。
■課題解決に向けたアプローチ
【対応方法】
・上記①~⑦の関数を用いた変更データの取得を廃止する。
・キャプチャインスタンス(cdc.{テーブル名}_CT)に直接クエリを発行し変更データを取得する。
【理由】
・sys.fn_cdc_map_time_to_lsn は目的外の変更データも含まれており、必要な変更データを取得するのにコストがかかる。
・キャプチャインスタンス(cdc.{テーブル名}_CT)へのアクセス手段が LSN のみとなっており、期間検索ができない。
■気になっていること
次のページに「システムテーブルに直接クエリを実行しないことをお勧めします。」との記載を見つけました。
https://learn.microsoft.com/ja-jp/sql/relational-databases/system-tables/cdc-capture-instance-ct-transact-sql?view=sql-server-ver16
関数の使用を推奨している理由や直接クエリを実行することによる弊害などございますか。