nishio-dens's diary

Railsとかプログラミング関連の備忘録

Profilerを使わずに、SQL Server Expressに発行されたクエリを取得する方法

最近マイブームのEntity Framework。データベースマイグレーションなんかも簡単にできちゃうし、とても便利なフレームワーク(O/Rマッパー)です。
Entity Framework Code Firstに関する解説なんかも書いちゃったりしてます( http://densan-labs.net/tech/codefirst/ )。

O/Rマッパーはとても便利なものですが、どんなクエリをSql Serverに対して発行しているかをキチンと理解して使わないと、時々痛い目を見ます。例えば、EFを使ってデータをInsertするには、以下のようなコードを書きます。

using (var context = new DbContext())
{
    context.Models.Add(new XXXModel{ ... });
    context.SaveChanges();
}

単純にデータをSql Serverにインサートしたいだけなのに、実はこれ、Insert文を発行後、こっそりSelect文も発行してたりします。

Entity Framework4.3の段階では、性能面で問題のあるクエリがDBに対して発行されていることが多々あります。
どんなSql文が発行されているかを把握することはとても重要ですが、残念ながら発行しているクエリを簡単に確認することはできません。
(EFの場合、Selectクエリはデバッガ等で確認することは可能です)

こういった場合、普通はSql Server Profiler等を使ってDBに発行されたクエリを確認するのでしょうが、お金のない私はSql Server Expressしかもっていません
(もちろんProfilerなんていう高価なものはついてません)。
Visual Studio Ultimateを持っていれば、IntelliTraceという超便利なトレーサーが使えますが、そんな高価なもの恐れ多くて触ることすらできません。

なんとかSql Server Expressに発行されたクエリを確認できないものか。調べてみると。。。なになに、Sql Serverにはトレースフラグという機能があると。これを使えば、発行されたクエリを確認できそうです。

結論から言うと、トレースフラグ3605と4032をオンにすることによって、Sql Serverのエラーログに発行されたクエリが表示されます。
4032はSql Serverが受け取ったコマンドをトレースするためのフラグです。3605はそのトレース結果をエラーログに出力するためのフラグです。

4032フラグは、SqlServer起動時に設定しないといけません。なので、SqlServerを起動している場合は、まずはサービスから停止させておきましょう。(下図のように状態が開始、になっている場合はSql Serverが起動していますので、停止させましょう)

その後、トレースフラグ4032をONにした状態でSQL Serverを起動するために、コマンドプロンプトを管理者モードで開き、以下のコマンドを入力してください。

net start MSSQL$SQLEXPRESS /T4032

次に、SQL SMSでSQL Serverにログイン後、以下のコマンドを発行します。

dbcc traceon(3605, -1)

これで準備完了です。クライアントからSql Serverに向けてクエリを発行後、エラーログを見てみましょう。
(エラーログ出力先は環境によって違いますが、多くの方は C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\Log\ERRORLOG にあると思われます)

TEXT: の後に発行されたクエリが表示されてます。やりました!