EntityFrameworkでToList()が極端に遅くなる
Q&A
Closed
解決したいこと
C# + Entity FrameworkアプリケーションでTake()
をかまさないToList()
が極端に遅い原因を知りたい。
プログラム作成中にリスト表示箇所が極端に遅かったため、VisualStudio
のデバッグ機能にて問題個所を調べたところ
ToList()
で極端に遅くなっていることに気づきました。
該当するソースコード
using (var db = new AppDbContext())
{
Decimal pKey1 = XXX;
Decimal pKey2 = XXXXX;
Decimal pCode = XX;
var r1 = db.V_DATA
.Where(s => s.Key1 == pKey1)
.Where(s => s.Key2 == pKey2)
.Where(s => s.Code <= pCode)
.ToList(); // ここで7,363ミリ秒(7秒程)かかる
}
============================
/// Entityクラス
public partial class V_DATA
{
[Key]
[Column(Order = 0, TypeName = "numeric")]
public decimal Key1 { get; set; }
[Key]
[Column(Order = 1, TypeName = "numeric")]
public decimal Key2 { get; set; }
[Key]
[Column(Order = 2, TypeName = "numeric")]
public decimal Key3 { get; set; }
[Key]
[Column(Order = 3)]
public string Column4 { get; set; } // 最大
[Key]
[Column(Order =4 , TypeName = "numeric")]
public decimal Column5 { get; set; }
[Key]
[Column(Order = 5, TypeName = "numeric")]
public decimal Column6 { get; set; }
}
ToList()
で取得される件数は100件
。試しにToList()
直前に生成されたSQLをSSMS
から実行しましたが
ほぼ0秒で結果が返ってきたためクエリチューニングの問題ではないように思えました。
var r1 = db.V_DATA
.Where(s => s.Key1 == pKey1)
.Where(s => s.Key2 == pKey2)
.Where(s => s.Code <= pCode)
.Selct(s => s); // デバッグモードで停止してSql文字列を取得
質問
以下の点についてご教示をお願い致します。
- Take()
無しで速度を向上する方法を知りたい。
- ToList()
のみで極端に遅くなる理由を知りたい。
なお、V_DATA
はSQLServer
データベースにおいてView
として定義されています。
検証したこと1(Take(100).ToList())⇒少し早くなる(及第点)
var r1 = db.V_DATA
.Where(s => s.Key1 == pKey1)
.Where(s => s.Key2 == pKey2)
.Where(s => s.Code <= pCode)
.Take(100) // ToList()で取得される件数と同数の100を指定
.ToList(); // 早くなった。⇒1,112ミリ秒(1秒程)
検証したこと2(ToArray)⇒遅い
var r1 = db.V_DATA
.Where(s => s.Key1 == pKey1)
.Where(s => s.Key2 == pKey2)
.Where(s => s.Code <= pCode)
.ToArray(); // ToArray化。同様に遅い。⇒7,576ミリ秒(7秒程)
検証したこと3(Any)⇒早い
var r1 = db.V_DATA
.Where(s => s.Key1 == pKey1)
.Where(s => s.Key2 == pKey2)
.Where(s => s.Code <= pCode)
.Any(); // Any()化。早い。⇒49ミリ秒(7秒程)
その他
V_DATA
ビューは概ね以下の定義になっています。
Column4の最大桁数は11桁
、その他数値項目は12桁
です。
[dbo].[V_DATA](
[Key1] [numeric](6, 0) NOT NULL,
[Key2] [numeric](7, 0) NOT NULL,
[Key3] [numeric](3, 0) NOT NULL,
[Column4] [nvarchar](max) NOT NULL,
[Column5] [numeric](22, 0) NOT NULL,
[Column6] [numeric](22, 0) NOT NULL,
)
利用バージョンなど
- Windows 10
- Windows Forms アプリケーション
- .NET Framework 4.8
- Entity Framework 6.2.0
- SQL Server 2014
困っています。ご回答お待ちしております。