最近非常に遅くなったコードをリファクタリングしようとしていて、実行に 5 秒以上かかるコード ブロックに遭遇しました。
このコードは、次の 2 つのステートメントで構成されています。
IEnumerable<int> StudentIds = _entities.Filters
.Where(x => x.TeacherId == Profile.TeacherId.Value && x.StudentId != null)
.Select(x => x.StudentId)
.Distinct<int>();
と
_entities.StudentClassrooms
.Include("ClassroomTerm.Classroom.School.District")
.Include("ClassroomTerm.Teacher.Profile")
.Include("Student")
.Where(x => StudentIds.Contains(x.StudentId)
&& x.ClassroomTerm.IsActive
&& x.ClassroomTerm.Classroom.IsActive
&& x.ClassroomTerm.Classroom.School.IsActive
&& x.ClassroomTerm.Classroom.School.District.IsActive).AsQueryable<StudentClassroom>();
少し面倒ですが、最初に 1 つのテーブル (フィルター) から Id の個別のリストを取得し、それを使用して別のテーブルにクエリを実行します。
これらは比較的小さなテーブルですが、それでもクエリ時間は 5 秒以上です。
これをLINQPadに入れたところ、最初に一番下のクエリを実行し、その後1000個の「個別の」クエリを実行していたことがわかりました。
気まぐれで、最後に .ToArray() を追加するだけで「StudentIds」コードを変更しました。これにより、速度が 1000 倍向上しました。同じクエリを完了するのに 100 ミリ秒ほどかかります。
どうしたんだ?私は何を間違っていますか?