0

200 万件のレコードをフィルター処理する次のメソッドがありますが、ほとんどの場合、最後のページを取得したい場合、エンティティ フレームワークがタイムアウトする原因となります。

 public virtual ActionResult GetData(DataTablesParamsModel param)
        {
            try
            {
                int totalRowCount = 0;
                // Generate Data
                var allRecords = _echoMediaRepository.GetMediaList();
                //Apply search criteria to data

                var predicate = PredicateBuilder.True<MediaChannelModel>();

                if (!String.IsNullOrEmpty(param.sSearch))
                {
                    var wherePredicate = PredicateBuilder.False<MediaChannelModel>();
                    int i;
                    if (int.TryParse(param.sSearch, out i))
                    {
                        wherePredicate = wherePredicate.Or(m => m.ID == i);
                    }
                    wherePredicate = wherePredicate.Or(m => m.Name.Contains(param.sSearch));

                    predicate = predicate.And(wherePredicate);
                }

                if (param.iMediaGroupID > 0)
                {
                    var wherePredicate = PredicateBuilder.False<MediaChannelModel>();

                    var mediaTypes = new NeptuneRepository<Lookup_MediaTypes>();
                    var mediaGroups = mediaTypes.FindWhere(m => m.MediaGroupID == param.iMediaGroupID)
                    .Select(m => m.Name)
                    .ToArray();

                    wherePredicate = wherePredicate.Or(m => mediaGroups.Contains(m.NeptuneMediaType) || mediaGroups.Contains(m.MediaType));
                    predicate = predicate.And(wherePredicate);
                }

                var filteredRecord = allRecords.Where(predicate);

                var columnCriteria = param.sColumns.Split(',').ToList();
                if (!String.IsNullOrEmpty(columnCriteria[param.iSortCol_0]))
                {
                    filteredRecord = filteredRecord.ApplyOrder(
                        columnCriteria[param.iSortCol_0],
                        param.sSortDir_0 == "asc" ? QuerySortOrder.OrderBy : QuerySortOrder.OrderByDescending);
                }

                totalRowCount = filteredRecord.Count();

                var finalQuery = filteredRecord.Skip(param.iDisplayStart).Take(param.iDisplayLength).ToList();

                // Create response
                return Json(new
                {
                    sEcho = param.sEcho,
                    aaData = finalQuery,
                    iTotalRecords = allRecords.Count(),
                    iTotalDisplayRecords = totalRowCount
                }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
                throw;
            }
        }
4

1 に答える 1

1

あなたのコードとクエリは最適化されているように見えるので、データベースにインデックスがなく、orderby (skip で使用) のパフォーマンスが低下することが問題であるはずです。

あなたのものと非常によく似たテストコードを使用して、ローカルテストDBで500万行のテーブル(XMLタイプの列がすべて埋められている)でいくつかのテストを行いましたが、予想通り、インデックスで並べ替えられたクエリを使用すると非常に高速でしたが、インデックスのない列では、非常に長い時間がかかる可能性があります。

動的な Where 関数と Order 関数で最もよく使用される列を分析し、対応するインデックスを作成してパフォーマンス テストを行うことをお勧めします。

于 2013-07-04T11:02:51.450 に答える