Activity
7 種類ほどの異なるモデルからモデルを取り込むモデルがあります。これらのモデルにも関係があり、必要な情報をアクティビティ フィードで表示できるようにする必要があります。これは、クエリに約 20 個のインクルードがあることを意味します。私はこれを8か月ほどしか行っていませんが、コンパイルされたクエリ、ストアドプロシージャ、およびそれらすべてのインクルードがおそらく私を殺している方法について読んだことがあります. また、遅延読み込みができるようにコード ファースト モデルを変更できることも読みましたvirtual
が、大量のユーザーを獲得した場合、これらすべてのデータベース呼び出しによってサイトが停止するのではないかと心配しています。
まずはモデル
public class Activity
{
public int ActivityID { get; set; }
public int ActivityTypeID { get; set; }
public int ContributorID { get; set; }
public int UserID { get; set; }
public int? ProjectID { get; set; }
public int? ProjectDocID { get; set; }
public int? CommentID { get; set; }
public int? BookID { get; set; }
public int? BookReviewID { get; set; }
public DateTime DateCreated { get; set; }
public Comment Comment { get; set; }
public ProjectDoc ProjectDoc { get; set; }
public Project Project { get; set; }
public Book Book { get; set; }
public BookReview BookReview { get; set; }
public ActivityType ActivityType { get; set; }
[ForeignKey("ContributorID")]
public User Contributor { get; set; }
[ForeignKey("UserID")]
public User User { get; set; }
public ICollection<ActivityLike> ActivityLike { get; set; }
public ICollection<ActivityComment> ActivityComment { get; set; }
}
今、クエリ
var activity = db.Activities
.Include(i => i.Contributor.BookStatus)
.Include(i => i.ActivityType)
.Include(i => i.ActivityLike.Select(y => y.User))
.Include(i => i.ActivityComment.Select(y => y.User))
.Include(i => i.Project.ProjectFollower)
.Include(i => i.Project.View)
.Include(i => i.Project.ProjectType)
.Include(i => i.Project.User)
.Include(i => i.Project.ProjectTag.Select(v => v.Tag))
.Include(i => i.Project.ProjectCategory.Select(v => v.Category))
.Include(i => i.Project.ProjectCharacteristic.Select(v => v.Characteristic))
.Include(i => i.Project.ProjectDoc.Select(v => v.ProjectDocVote))
.Include(i => i.Project.ProjectDoc.Select(v => v.User))
.Include(i => i.Comment.User)
.Include(i => i.Book.Author)
.Include(i => i.Book.BookReview.Select(v => v.User))
.Include(i => i.Book.BookReview.Select(v => v.BookReviewVote))
.Include(i => i.Book.BookCharacteristic.Select(v => v.Characteristic))
.Include(i => i.Contributor.Followers)
.Where(u =>
u.Contributor.Followers.FirstOrDefault(x => x.FollowerID == WebSecurity.CurrentUserId) != null
)
.OrderByDescending(d => d.DateCreated)
.Skip(offset)
.Take(results)
.ToList();
これは最終的に 6600 行の SQL (またはそれが何であれ) のようになります。
これを初めて実行するときは、10 ~ 16 秒かかります。またSkip()
、jquery で無限スクロールを使用しているため、最初の ajax 呼び出しごとに 10 ~ 12 秒かかります。したがって、一度に 10 件の結果が得られ、100 件の結果がある場合、100 秒を超える待機時間になります。これはひどいことです。次にユーザーがそのページに短時間でアクセスするときは、非常に迅速です。
では、このクエリをどのように改善すればよいのでしょうか。また、コンパイルされたクエリとそうでないものを理解するのが難しいため、具体的にその方法を提供して解決策を説明していただけますか。私がここまでたどり着くことができた唯一の理由は、EF によって簡単になったからです...これには明らかにコストがかかります。
用語の誤用をご容赦ください。