3

編集:可能な限り最高のパフォーマンスを得るには、これらのlinqクエリをSQLクエリに書き直すためのヘルプが必要です。

約1,000万行のテーブルがあります。Idを含む7列で構成されています。最初はId、次に「TradeObjectModel」への3つのキー、最後に3つの整数が異なるTradeObjectModels評価値を保持します。このような: ここに画像の説明を入力してください

キー71を持つTo1Id(TradeObjectModel1所有者)などのユーザーが他のTradeオブジェクトの評価を処理する場合、現在のビューには1行だけで十分です。

これを解決するための私の試みは次のようになります(コードサンプルの下の説明):

IEnumerable<RatingListTriangleModel> allTriangleModels1 =
                this._ratingListTriangleRepository.All.Where(
                    ratingListRow =>
                    ratingListRow.To1Id == myTradeObject.TradeObjectId);
            var filteredallTriangleModels1 = from row in allTriangleModels1
                                             group row by row.To2Id into g
                                             select g.First();


            IEnumerable<RatingListTriangleModel> allTriangleModels2 =
                this._ratingListTriangleRepository.All.Where(
                    ratingListRow =>
                   ratingListRow.To2Id == myTradeObject.TradeObjectId);
            var filteredallTriangleModels2 = from row in allTriangleModels2
                                             group row by row.To3Id into g
                                             select g.First().

            IEnumerable<RatingListTriangleModel> allTriangleModels3 =
                this._ratingListTriangleRepository.All.Where(
                    ratingListRow =>
                   ratingListRow.To3Id == myTradeObject.TradeObjectId);

            var filteredallTriangleModels3 = from row in allTriangleModels3
                                             group row by row.To1Id into g
                                             select g.First();


            var fileredallTriangleModels =
                filteredallTriangleModels1.Union(filteredallTriangleModels2).Union(filteredallTriangleModels3).ToList();


            ViewBag.TriangleCount = fileredallTriangleModels.Count();

            foreach (var ratingListRow in fileredallTriangleModels)
            {
                //Find which one is my ad and set me as setter and their object as receiver
                if (ratingListRow.To1Id == customer.TradeObjectId)
                {
                    var ri = new TriangleViewModel(
                        customer.TradeObjectId,
                        this._customerRepository.FindTradeObjectId(ratingListRow.To2Id),
                        ratingListRow,
                        this._tradeobjectRepository.Find(ratingListRow.To2Id));

                    model.Models3.Add(ri);
                    continue;
                }

                if (ratingListRow.To2Id == customer.TradeObjectId)
                {
                    var ri = new TriangleViewModel(
                        customer.TradeObjectId,
                        this._customerRepository.FindTradeObjectId(ratingListRow.To3Id),
                        ratingListRow,
                        this._tradeobjectRepository.Find(ratingListRow.To3Id));

                    model.Models3.Add(ri);
                    continue;
                }

                if (ratingListRow.To3Id == customer.TradeObjectId)
                {
                    var ri = new TriangleViewModel(
                        customer.TradeObjectId,
                        this._customerRepository.FindTradeObjectId(ratingListRow.To1Id),
                        ratingListRow,
                        this._tradeobjectRepository.Find(ratingListRow.To1Id));
                    model.Models3.Add(ri);
                }
            }

最初に、オブジェクトが最初の列にあるすべての行を取得し、それらをグループ化して1つだけを選択してから、2番目と3番目の列で同じことを続けます。ここでのToList()は、medがストップウォッチを実行できるようにするための一時的なものであり、それぞれ0〜12秒かかります。次に、それらを結合し、それらすべてを実行して、フロントエンドコードでWebグリッドによって使用されるモデルを作成します。

これは2つの問題を引き起こします:1。それは多くから長い時間がかかります。2.トレードオブジェクトIDが複数の列にある場合、関心のあるトレードオブジェクトの複数を表す複数の行が表示されます。

4

3 に答える 3

1

プロファイラーを使用してクエリをキャプチャし、最も長く実行されている上位3つのクエリを分離してみてください。それらをSSMSにコピーして実行します。実際の実行計画を探します。テーブルスキャン、または推定レコード数と実際のレコード数の間の大きな不一致を探します。ここから、統計がオフになっているか、クエリをカバーするためにインデックスを配置することを検討できます。

于 2013-01-04T11:02:57.053 に答える
1

Database Engine Tuning Advisorを使用して、テーブルのインデックスを追加/削除/変更すると、LINQクエリによって提示されるワークロードのパフォーマンスが大幅に向上するかどうかを確認してください。

于 2013-01-03T09:49:23.670 に答える
1

パフォーマンスの観点からは、ある種のストアド プロシージャを使用する方がよい場合があります。LINQ は、これらのタイプのクエリ/ルックアップを使用すると、処理が大幅に遅くなる傾向があります。ただし、ストアド プロシージャだけでは不十分な場合は、できることがいくつかあります。

まず、 Incremental Searchを見てみることをお勧めします。これは、基本的に検索を継続するか、一定時間実行を「延期」するだけで作成されます。これは、IEnumerable で動作するはずです。

次にお勧めするのは、上記のインクリメンタル検索に似たものを (追加関数などを使用して) 統合して、プログラムで動作するものに対して同様の実装を作成できるかどうかを確認することです。

真剣に-私は過去にストアド プロシージャからの大幅な改善を見てきました。これにより、速度が確実に向上します (私の場合、1 つのクエリがほぼ 10 分の 1 に削減されました!)

于 2013-01-10T19:30:33.447 に答える