EF ベースのアプリケーションの起動時間を短縮しようとしていますが、単一エンティティ コンテキストであっても、最初の読み取りにかかる時間を 7 秒未満に短縮できないことがわかりました。特に奇妙なのは、今回はコンテキスト タイプ固有ではないことです。
これらの遅い時間の原因や、物事をより速く実行する方法を誰かが説明できますか?
完全なサンプル コードは次のとおりです。
私のデータベースには、主キー列 AptId を持つ se_stores という名前のテーブルがあります。
// a sample entity class
public class Apartment
{
public int AptId { get; set; }
}
// two identical DbContexts
public class MyDbContext1 : DbContext
{
public MyDbContext1(string connectionString) : base(connectionString)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer<MyDbContext1>(null);
var config = new EntityTypeConfiguration<Apartment>();
config.HasKey(a => a.AptId).ToTable("se_stores");
modelBuilder.Configurations.Add(config);
base.OnModelCreating(modelBuilder);
}
}
public class MyDbContext2 : DbContext
{
public MyDbContext2(string connectionString)
: base(connectionString)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer<MyDbContext2>(null);
var config = new EntityTypeConfiguration<Apartment>();
config.HasKey(a => a.AptId).ToTable("apartments");
modelBuilder.Configurations.Add(config);
base.OnModelCreating(modelBuilder);
}
}
// finally, I run this code using NUnit:
var start = DateTime.Now;
var apt1 = new MyDbContext1(connectionString).Set<Apartment>().FirstOrDefault();
var t1 = DateTime.Now - start;
start = DateTime.Now;
var apt2 = new MyDbContext2(connectionString).Set<Apartment>().FirstOrDefault();
var t2 = DateTime.Now - start;
Console.WriteLine(t1.TotalSeconds + ", " + t2.TotalSeconds);
次のようなものが確実に出力されます: 7.5277527, 0.060006。最初に MyDbContext2 を使用するようにテストを切り替えると、同じ結果が得られます (したがって、最初に初期化された DbContext に対して発生します)。また、EF パワー ツールを使用してビューを事前に生成しようとしました。これにより、最初のコンテキストの時間が約 6.8 秒に短縮され、小さな勝利に過ぎませんでした。
DateTime.Now がひどいプロファイリング方法であることは理解していますが、dotTrace を使用している間、これらの結果は維持されています。また、一部のコードを初めて実行すると JITing コストが発生することも認識していますが、7 秒という値は、その原因とするには高すぎるようです。
VS 2010 で EF 4.3.1 と .NET 4 を使用しています。
よろしくお願いします。
編集:SQL接続を開くと問題が発生する可能性があることが示唆されました。
- 最初に、生の SqlConnection を使用してランダム クエリを実行し、同じ接続文字列でコマンドを作成してみました。これには 1 秒かかり、DbContext の初期化時間には影響しませんでした。
- 次に、接続文字列を使用して SqlConnection を作成し、それを接続を受け取る DbContext のコンストラクターに渡してみました。contextOwnsConnection=false を渡しました。これも、DbContext の初期化時間に違いはありませんでした。
- 最後に、同じ資格情報と接続文字列オプションを使用して、管理スタジオ経由で接続を試みました。これはほぼ瞬時でした。
- dotTrace プロファイルでは、SqlConnectionFactory.CreateConnection(connectionString) が 0.7 秒かかると測定されます。これは生の SQL 時間と一致しています。
編集: 遅延が接続ごとに発生したのか、1 回だけだったのかを知りたいと思いました。したがって、 MyDbContext1 と MyDbContext2 を異なるサーバー上のまったく異なるデータベースに接続しようとしました。これは、最初に接続されたデータベースに関係なく、違いはありませんでした。最初の DbContext の使用には約 7 秒かかりましたが、2 番目のコンテキストの使用は非常に高速です。