sql >> データベース >  >> RDS >> Sqlserver

Sql プロファイラーを使用して SqlBulkCopy で渡されたデータをキャプチャするにはどうすればよいですか?

    一括挿入操作のイベント情報のキャプチャ ( BCP.EXESqlBulkCopy 、そして BULK INSERT を想定しています 、および OPENROWSET(BULK... ) は可能ですが、個々の行と列を表示することはできません。

    一括挿入操作は、次の 1 つの DML ステートメントとして表示されます (つまり、バッチごとに 1 つ、デフォルトでは 1 つのバッチですべての行を実行することです)。

    INSERT BULK <destination_table_name> (
          <column1_name> <column1_datatype> [ COLLATE <column1_collation> ], ...
          ) [ WITH (<1 or more hints>) ]
    
    <hints> := KEEP_NULLS, TABLOCK, ORDER(...), ROWS_PER_BATCH=, etc
    

    BCP の MSDN ページで「ヒント」の完全なリストを見つけることができます。ユーティリティ . SqlBulkCopy はこれらのヒントのサブセットのみをサポートすることに注意してください (例:KEEP_NULLSTABLOCK 、およびその他のいくつか) が、しない ORDER(...) をサポート または ROWS_PER_BATCH= (実際には、ORDER() として非常に残念です tempdb で発生する並べ替えを回避して操作のログを最小限に抑えるには、ヒントが必要です (そのような操作の他の条件も満たされていると仮定します)。

    このステートメントを表示するには、SQL Server Profiler で次のイベントのいずれかをキャプチャする必要があります:

    また、少なくとも次の列を (SQL Server プロファイラーで) 選択する必要があります。

    また、ユーザーは INSERT BULK を送信できないため、 これらのイベントのみを表示したいだけの場合は、おそらく [列フィルター] でそれをフィルター処理できます。

    BULK INSERT の公式通知を見たい場合 操作が開始および/または終了している場合、次のイベントをキャプチャする必要があります:

    次に、次のプロファイラー列を追加します:

    ObjectName の場合 「BULK INSERT」を示すイベントを常に取得し、それが開始か終了かは EventSubClass の値によって決まります 、これは「0 - 開始」または「1 - コミット」のいずれかです (失敗した場合は、「2 - ロールバック」が表示されるはずです)。

    ORDER() の場合 ヒントが指定されていません (また、できません SqlBulkCopy を使用するときに指定する )、その後、ObjectName に "sort_init" を示す "SQLTransaction" イベントも取得します。 桁。このイベントには、「0 - 開始」イベントと「1 - コミット」イベントもあります (EventSubClass に示されているように)。 列)

    最後に、特定の行は表示されませんが、次のイベントをキャプチャすると、トランザクション ログに対する操作 (行の挿入、IAM 行の変更、PFS 行の変更など) を確認できます:

    次のプロファイラー列を追加します:

    関心のある主な情報は EventSubClass にあります 残念ながら、これは単なる ID 値であり、MSDN ドキュメントでこれらの値の翻訳を見つけることができませんでした。しかし、Jonathan Kehayias による次のブログ投稿を見つけました。 -in-sql-server-denali-ctp1-to-map-out-the-transactionlog-sql-trace-event-eventsubclass-values.aspx">SQL Server Denali CTP1 で拡張イベントを使用して TransactionLog SQL トレース イベントをマップするEventSubClass 値 .

    @RBarryYoung は、EventSubClass の値と名前が sys.trace_subclass_values で見つかることを指摘しました カタログ ビューですが、そのビューをクエリすると、TransactionLog の行がないことが示されます イベント:

    SELECT * FROM sys.trace_categories -- 12 = Transactions
    SELECT * FROM sys.trace_events WHERE category_id = 12 -- 54 = TransactionLog
    SELECT * FROM sys.trace_subclass_values WHERE trace_event_id = 54 -- nothing :(
    

    SqlBulkCopy.BatchSize に注意してください。 プロパティは -b を設定するのと同じです BCP.EXE のオプション 、これは、各コマンドが行をセットに分割する方法を制御する操作設定です。これは ROWS_PER_BATCH= と同じではありません ヒントは、行をセットに分割する方法を物理的に制御するのではなく、代わりに SQL Server がページを割り当てる方法をより適切に計画できるようにするため、トランザクション ログのエントリ数を (場合によってはかなり) 減らします。それでも、私のテストでは次のことが示されました:

    • -b の指定 BCP.EXEROWS_PER_BATCH= を設定しました その同じ値へのヒント。
    • SqlBulkCopy.BatchSize の指定 しなかった ROWS_PER_BATCH= を設定します ヒントはありますが、トランザクション ログ アクティビティの削減によるメリットは、何らかの形で確かにありました (魔法のように?)。 ORDER() が ヒントは SqlBulkCopy でサポートされていませんでした .


    1. phpを使用してjsonでmysqlデータベーステーブルデータを変換する方法

    2. Javaのシーケンシャルストリームとパラレルストリームとは何ですか?

    3. UPDATEのmysqli_affected_rowsは、完全な行の一致で0を返すことがあります

    4. MYSQLの日付に基づいてレコードをフェッチする方法