3

编辑:我需要帮助将这些 linq 查询重写为 SQL 查询以获得尽可能高的性能。

我有一张大约有 1000 万行的表。它由 7 列组成,包括 Id。首先是 Id,然后是“TradeObjectModel”的三个键,最后是保持不同 TradeObjectModels 评级值的三个整数。像这样: 在此处输入图像描述

当用户,例如 To1Id (TradeObjectModel1 所有者) 使用键 71 处理她对其他贸易对象的评级时,只有一行足以满足当前视图。

我解决这个问题的尝试看起来像这样(代码示例下面的解释):

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);
                }
            }

首先,我得到我的对象在第一列的所有行,将它们分组以仅选择一个,然后在第二列和第三列继续对我做同样的事情。这里的 ToList() 只是临时的,让 med 能够在它们上运行秒表,每个都需要 0-12 秒。然后我加入他们并运行所有这些以在前端代码中创建 webgrid 使用的模型。

这会导致两个问题: 1. 需要很长时间。和 2. 如果我的贸易对象 ID 位于不止一列,我将获得不止一行,显示不止一个我感兴趣的贸易对象。

4

3 回答 3

1

尝试使用数据库引擎优化顾问来查看添加/删除/更改表上的索引是否显着提高了 LINQ 查询提供的工作负载的性能。

于 2013-01-03T09:49:23.670 回答
1

尝试使用分析器捕获您的查询并隔离前 3 个运行时间最长的查询。将它们复制到 SSMS 中并执行它们。寻找实际的执行计划。查找表扫描或估计记录数与实际记录数之间的巨大差异。从这里开始,要么统计信息关闭,要么您可以考虑放置一个索引来覆盖查询。

于 2013-01-04T11:02:57.053 回答
1

从性能的角度来看,使用某种存储过程可能会更好。LINQ 往往会通过这些类型的查询/查找来减慢速度。但是,如果存储过程还不够,您可以做一些事情。

首先,您可能想看看Incremental Search,它基本上是通过保持搜索继续或“延迟”执行给定时间而编写的。这应该适用于任何 IEnumerable。

我建议的下一件事是看看您是否可以潜在地集成类似于上面的增量搜索的东西(通过使用添加函数等),以便为任何适用于您的程序的东西进行类似的实现。

不过说真的 - 我过去已经看到存储过程的巨大改进,这肯定会提高速度(在我的例子中,一个查询减少了近 10 倍!)

于 2013-01-10T19:30:33.447 回答