2

このクエリは少し前に弊社のシステムで作成されたものですが、データが少し増えると、このクエリのパフォーマンスが低下します。私の調査では、( CodeCount) クエリが別のサブクエリを起動し、実行に大幅な遅延を引き起こしていることがわかりました。この Linq クエリを最適化する必要があります。どんな助けでも大歓迎です

  from batch in Context.VoucherCodeBatch.ToList()
                    join type in Context.VoucherCodeType on batch.VoucherTypeId equals type.VoucherTypeId
                    join voucher in Context.Voucher on batch.VoucherCodeBatchId equals voucher.VoucherCodeBatchId

                    where batchIds.Contains(batch.BatchCode)
                    group new
                    {
                        batch.BatchCode,
                        batch.CreationDate,
                        type.VoucherTypeName,
                        voucher.AllowedCount,
                        voucher.ValidFrom,
                        voucher.ValidTo,
                        batch.VoucherCodeBatchId,
                        voucher.VoucherCode
                    }
                        by new { batch.BatchCode }
                        into uniquebatch
                        select new Batch
                        {
                            BatchCode = uniquebatch.FirstOrDefault().BatchCode,
                            CreationDate = uniquebatch.FirstOrDefault().CreationDate,
                            TimesAllowed = uniquebatch.FirstOrDefault().AllowedCount,
                            ValidFrom = uniquebatch.FirstOrDefault().ValidFrom,
                            CodeCount = ((from c in Context.Voucher.ToList()
                                          where
                                              c.VoucherCodeBatchId ==
                                              uniquebatch.FirstOrDefault().VoucherCodeBatchId
                                          select c).Count()),
                            ValidTo = uniquebatch.FirstOrDefault().ValidTo,
                            CodeType = uniquebatch.FirstOrDefault().VoucherTypeName,
                            VoucherCodeBatchId = uniquebatch.FirstOrDefault().VoucherCodeBatchId
                        });
4

1 に答える 1

1

最初の大きな問題はToList()、ObjectSet<> (EF のテーブル コレクション) の直前にあります。

ToList()クエリを処理する前に、EF がすべてのデータをメモリに移動するように強制します。(@Daniel Hilgarth のコメントのように)。

FirstOrDefault()その他の詳細は、次の行の前に get プロパティを使用することです。

BatchCode = uniquebatch.FirstOrDefault().BatchCode,

この場合はFirst()代わりに使用してください。FirstOrDefaultお気に入り:

BatchCode = uniquebatch.First().BatchCode,

クエリは次のようになります。

from batch in Context.VoucherCodeBatch/*.ToList()*/
join type in Context.VoucherCodeType on batch.VoucherTypeId equals type.VoucherTypeId
join voucher in Context.Voucher on batch.VoucherCodeBatchId equals voucher.VoucherCodeBatchId
where batchIds.Contains(batch.BatchCode)
group new
    {
        batch.BatchCode,
        batch.CreationDate,
        type.VoucherTypeName,
        voucher.AllowedCount,
        voucher.ValidFrom,
        voucher.ValidTo,
        batch.VoucherCodeBatchId,
        voucher.VoucherCode
    }
by new { batch.BatchCode }
into uniquebatch
select ( delegate
    {
        // If you put a operation in a query that operation will be
        // processed all times. Bacause that i removed this line from
        // the where statement.
        var vcBatchId = uniquebatch.First().VoucherCodeBatchId;

        return new Batch
            {
                BatchCode = uniquebatch.First().BatchCode,
                CreationDate = uniquebatch.First().CreationDate,
                TimesAllowed = uniquebatch.First().AllowedCount,
                ValidFrom = uniquebatch.First().ValidFrom,
                CodeCount = ((
                    from c in Context.Voucher/*.ToList()*/
                    where c.VoucherCodeBatchId == vcBatchId
                    select c).Count()),
                ValidTo = uniquebatch.First().ValidTo,
                CodeType = uniquebatch.First().VoucherTypeName,
                VoucherCodeBatchId = uniquebatch.First().VoucherCodeBatchId
            }
    });

この改善が十分でない場合は、このクエリを SQL に変更する必要があります。しかし、私はこの改善がはるかに優れたパフォーマンスを発揮すると信じています.

于 2013-06-04T13:04:56.087 に答える