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

bulkinsert sqlbulkcopy sql-server sql-server-2012 sql-server-profiler

質問

私はSQLプロファイラを使用してSQL文をキャプチャし、問題のあるSQL文を再実行しています。非常に便利。

しかし、一部のコードではSqlBulkCopy APIを使用しているため、これらをキャプチャする方法はわかりません。私は一時テーブルの作成を参照してください。 SqlBulkCopyがSql Profilerをバイパスしているか、適切なイベントをキャプチャしていないようです。

人気のある回答

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

一括挿入操作は単一のものとして表示されます(よくバッチごとに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:バッチ起動
SQL:BatchCompleted
SQL:StmtStarting
SQL:StmtCompleted

SQL Server Profilerでは、少なくとも次の列を選択することもできます。

TextData
CPU
読書
書き込み
期間
SPID
始まる時間
終了時間
RowCounts

また、ユーザーはINSERT BULK文を直接提出できないため、これらのイベントだけを表示したいだけであれば、列フィルタでその文をフィルタリングできます。

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

SQLTransaction

次のProfiler列を追加します。

EventSubClass
ObjectName

ObjectName場合は、常に "BULK INSERT"を示すイベントが発生し、開始または終了のどちらがEventSubClassの値( "0 - Begin"または "1 - Commit")によって決まるかが決まります。 「2 - ロールバック」を参照)。

ORDER()ヒントが指定されていない場合ORDER() SqlBulkCopyを使用する場合は指定できません )、 ObjectName列に "sort_init"を示す "SQLTransaction"イベントが表示されます。このイベントには、 EventSubClass列に示されているように、 "0 - Begin"および "1 - Commit"イベントもあります。

最後に、特定の行が表示されない場合でも、次のイベントをキャプチャすると、トランザクションログに対して操作が表示されます(行の挿入、IAM行の変更、PFS行の変更など)

TransactionLog

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

ObjectID

関心のある主な情報はEventSubClass列にありますが、残念ながらそれは単なるID値であり、MSDNのドキュメントではこれらの値の翻訳を見つけることができませんでした。しかし、私はJonathan Kehayiasの次のブログ記事を見つけました。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プロパティは、 SqlBulkCopy.BatchSize-bオプションを設定するのと同じです.BCP.EXEは、各コマンドが行をセットに分割する方法を制御する操作設定です。これは、行がセットに分割される方法を物理的に制御しないROWS_PER_BATCH=ヒントと同じではなく、SQL Serverがページをどのように割り当てるかを計画することを可能にし、トランザクションログのエントリ数を減らしますときにはかなりのビットで)。それでも私のテストでは、

  • BCP.EXEの -bを指定すると、 ROWS_PER_BATCH=ヒントが同じ値に設定されました。
  • SqlBulkCopy.BatchSizeプロパティを指定してもROWS_PER_BATCH=ヒント設定されませんでしたが、トランザクションログのアクティビティが削減されたというメリットがあったのです(魔法?)。正味の効果が依然として利益を得ることであるという事実は、 ORDER()ヒントがSqlBulkCopyによってサポートされていなかったことが残念だと言ったとき、私はトップに向かって言及しなかったのSqlBulkCopy


ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ