興味深い状況があります。 Microsoft SQL Server Management StudioのリモートSQLサーバーでクエリを実行すると、高速(12秒)が実行されますが、DbContext.Database.SqlQuery<EntityType>(script)
を使用してEntity Frameworkで同じクエリを実行すると48秒かかります。Entity Frameworkデータの読み取りパフォーマンス
私はset arithabort on
を設定してみました。設定は適用されましたが、パフォーマンスは変更されませんでした。私はSQLサーバー上のアクセス権が限られているため、クエリ実行プランを提供することはできません。しかし、これはクエリの問題ではないと私は100%言うことができます。
declare @t table (...)
insert into @t
select <long query>
select top 1 * from @t
@t
変数を約35Kの行が含まれています
は、このクエリを検討してください。実行時間は、EFとSSMSでほぼ同じです。しかし、私がtop 1
を削除すると、奇妙なことが起こり始める。 SSMSでは私は10秒、EFでは約40秒です。
私はこの小さな実験は、SQL Serverの可能性、間違った実行計画を選択し、物事を減速を排除することができますね。
もう1つ注目すべき点は、EFによってエンティティのマテリアライゼーションが行われることです。私はこれもボトルネックではないと思います。類似のサイズの結果をローカルSQL Expressに設定して同様のクエリを実行すると、どちらの場合でもほぼ即時に結果が得られます。
私の次の推測はネットワークの問題です。 Microsoft Network Monitor 3.4をインストールし、SSMSとEFの両方のネットワークトラフィックを監視しました。私が見つけた興味深いのは何らかの理由で、EF版にはより小さなサイズのパケットといくつかのTLSパケットがたくさんあるからです。 SSMSバージョンでは、パケットサイズはより安定しており、TLSパケットはありません。
問題は次のとおりです。EFバージョンのスピードアップが可能ですか?それらのTLSパケットは何ですか、それらを取り除くことは可能ですか?
更新
Entity Frameworkのv6.1.3
の.NET V4.5.1
SQL Serverのv10.50.2550.0
ローカルから[SQLExpressのv12.0.4213.0
のWindows 7プロ
更新
using (var connection = new SqlConnection(DbContext.Database.Connection.ConnectionString))
using (var cmd = new SqlCommand(script, connection))
{
connection.Open();
cmd.CommandType = CommandType.Text;
using (SqlDataReader reader = cmd.ExecuteReader())
{
reader.Read();
do
{
} while (reader.Read());
}
}
このコードでは、時間的に同じ結果が得られます。