ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# EF Core Or修改为Union优化,速度大幅度提升!

2022-08-05 17:33:46  阅读:146  来源: 互联网

标签:&& Core gr GivePageCount c# EF item Key CustomerId


最近在优化代码时发现linq 采用了||查询导致查询效率非常慢,查询语句出现扫表情况,

采用了Union大大提升了效率,解决了问题

优化c# 前的linq:

dateTime = dateTime.Date;
            DateTime BegTime = dateTime;
            DateTime EndTime = dateTime.AddDays(1);
            var v = from q in _MyDbContext.Document
                    where q.Customer.AgentId == agentId && (!q.UserRefundId.HasValue || q.UserRefund.RefundStatus != RefundStatusType.SUCCESS)
                    && ((q.OutputTime >= BegTime && q.OutputTime <= EndTime && q.DocumentStatus == DocumentStatus.OutputComplete)
                    || (q.Order.Status == OrderStatusType.SUCCESS && q.Order.SuccessTime >= BegTime && q.Order.SuccessTime <= EndTime))
                    select new PrinterStatisticsDto
                    {
                        PrinterId = q.PrinterId,
                        PrinterName = q.PrinterName,
                        CustomerId = q.CustomerId.Value,
                        CustomerName = q.Customer.Name,
                        JobType = q.JobType,
                        SimpleDuplexType = q.SimpleDuplexType == SimpleDuplexType.Simple ? SimpleDuplexType.Simple : SimpleDuplexType.DuplexLong,
                        PageSize = q.PageSize,
                        ColorType = q.ColorType,
                        PageCount = q.CalculationCount > 0 ? q.CalculationCount : q.PageCount,
                        Copies = q.Copies,
                        GivePageCount = q.GivePageCount,
                        TotalCost = (q.OrderId.HasValue && q.Order.Status == OrderStatusType.SUCCESS) ? q.TotalCost : 0
                    };
            var s = from item in v
                    group item by new
                    {
                        item.PrinterId,
                        item.PrinterName,
                        item.CustomerId,
                        item.CustomerName,
                        item.JobType,
                        item.PageSize,
                        item.ColorType,
                        item.SimpleDuplexType
                    } into gr
                    select new StatisticsDto
                    {
                        Balance = gr.Sum(a => a.TotalCost.Value),
                        ColorType = gr.Key.ColorType,
                        Count = gr.Sum(a => a.PageCount * a.Copies),
                        JobType = gr.Key.JobType,
                        SimpleDuplexType = gr.Key.SimpleDuplexType,
                        PageSize = gr.Key.PageSize,
                        PrinterName = gr.Key.PrinterName,
                        PrinterId = gr.Key.PrinterId,
                        CustomerId = gr.Key.CustomerId,
                        CustomerName = gr.Key.CustomerName,
                        GivePageCount = gr.Sum(a => a.GivePageCount),
                    };
            return s.ToList();

这样的代码生成的sql 语句如下:

SELECT SUM(CASE
    WHEN `d`.`OrderId` IS NOT NULL AND (`o`.`Status` = 1) THEN `d`.`TotalCost`
    ELSE 0
END) AS `Balance`, `d`.`ColorType`, SUM(CASE
    WHEN `d`.`CalculationCount` > 0 THEN `d`.`CalculationCount`
    ELSE `d`.`PageCount`
END * `d`.`Copies`) AS `Count`, `d`.`JobType`, CASE
    WHEN `d`.`SimpleDuplexType` = 1 THEN 1
    ELSE 2
END AS `SimpleDuplexType`, `d`.`PageSize`, `d`.`PrinterName`, `d`.`PrinterId`, `d`.`CustomerId`, COUNT(*) AS `OrderNumber`, SUM(`d`.`GivePageCount`) AS `GivePageCount`, timestamp('2022-08-04 00:00:00') AS `DateTime`
FROM `Document` AS `d`
LEFT JOIN `UserRefund` AS `u` ON `d`.`UserRefundId` = `u`.`Id`
LEFT JOIN `Order` AS `o` ON `d`.`OrderId` = `o`.`Id`
LEFT JOIN `Customer` AS `c` ON `d`.`CustomerId` = `c`.`Id`
WHERE ((`d`.`CustomerId` = 100076) AND (`d`.`UserRefundId` IS NULL OR ((`u`.`RefundStatus` <> 3) OR `u`.`RefundStatus` IS NULL))) AND ((((`d`.`OutputTime` >= timestamp('2022-08-04 00:00:00')) AND (`d`.`OutputTime` <= timestamp('2022-08-05 00:00:00'))) AND (`d`.`DocumentStatus` = 9)) OR (((`o`.`Status` = 1) AND (`o`.`CreateTime` >= timestamp('2022-08-04 00:00:00'))) AND (`o`.`CreateTime` <= timestamp('2022-08-05 00:00:00'))))
GROUP BY `d`.`PrinterId`, `d`.`PrinterName`, `d`.`CustomerId`, `c`.`Name`, `d`.`JobType`, `d`.`PageSize`, `d`.`ColorType`, CASE
    WHEN `d`.`SimpleDuplexType` = 1 THEN 1
    ELSE 2
END
ORDER BY `d`.`PrinterId` DESC, `d`.`JobType`
LIMIT 100 OFFSET 0

 

通过优化linq后代码如下,这样效率大大提升,没有出现扫表情况:

dateTime = dateTime.Date;
            DateTime BegTime = dateTime;
            DateTime EndTime = dateTime.AddDays(1);
            var v = from q in _MyDbContext.Document
                    where q.CustomerId == customerId
                    && (!q.UserRefundId.HasValue || q.UserRefund.RefundStatus != RefundStatusType.SUCCESS)
                    && (q.OutputTime >= BegTime && q.OutputTime <= EndTime && q.DocumentStatus == DocumentStatus.OutputComplete)
                    select new PrinterStatisticsDto
                    {
                        PrinterId = q.PrinterId,
                        PrinterName = q.PrinterName,
                        CustomerId = q.CustomerId.Value,
                        CustomerName = q.Customer.Name,
                        JobType = q.JobType,
                        SimpleDuplexType = q.SimpleDuplexType == SimpleDuplexType.Simple ? SimpleDuplexType.Simple : SimpleDuplexType.DuplexLong,
                        PageSize = q.PageSize,
                        ColorType = q.ColorType,
                        PageCount = q.CalculationCount > 0 ? q.CalculationCount : q.PageCount,
                        Copies = q.Copies,
                        GivePageCount = q.GivePageCount,
                        TotalCost = (q.OrderId.HasValue && q.Order.Status == OrderStatusType.SUCCESS) ? q.TotalCost : 0
                    };
            var v1 = from q in _MyDbContext.Document
                     where q.CustomerId == customerId
                     && (!q.UserRefundId.HasValue || q.UserRefund.RefundStatus != RefundStatusType.SUCCESS)
                     && q.Order.Status == OrderStatusType.SUCCESS && q.Order.SuccessTime >= BegTime && q.Order.SuccessTime <= EndTime
                     select new PrinterStatisticsDto
                     {
                         PrinterId = q.PrinterId,
                         PrinterName = q.PrinterName,
                         CustomerId = q.CustomerId.Value,
                         CustomerName = q.Customer.Name,
                         JobType = q.JobType,
                         SimpleDuplexType = q.SimpleDuplexType == SimpleDuplexType.Simple ? SimpleDuplexType.Simple : SimpleDuplexType.DuplexLong,
                         PageSize = q.PageSize,
                         ColorType = q.ColorType,
                         PageCount = q.CalculationCount > 0 ? q.CalculationCount : q.PageCount,
                         Copies = q.Copies,
                         GivePageCount = q.GivePageCount,
                         TotalCost = (q.OrderId.HasValue && q.Order.Status == OrderStatusType.SUCCESS) ? q.TotalCost : 0
                     };
            v = v.Union(v1);
            var s = from item in v
                    group item by new
                    {
                        item.PrinterId,
                        item.PrinterName,
                        item.CustomerId,
                        item.CustomerName,
                        item.JobType,
                        item.PageSize,
                        item.ColorType,
                        item.SimpleDuplexType
                    } into gr
                    select new PrinterStatistics
                    {
                        Balance = gr.Sum(a => a.TotalCost.Value),
                        ColorType = gr.Key.ColorType,
                        Count = gr.Sum(a => a.PageCount * a.Copies),
                        JobType = gr.Key.JobType,
                        SimpleDuplexType = gr.Key.SimpleDuplexType,
                        PageSize = gr.Key.PageSize,
                        PrinterName = gr.Key.PrinterName,
                        PrinterId = gr.Key.PrinterId,
                        CustomerId = gr.Key.CustomerId,
                        GivePageCount = gr.Sum(a => a.GivePageCount),
                        OrderNumber = gr.Count(),
                        DateTime = dateTime,
                    };

            return s.ToList();

 

标签:&&,Core,gr,GivePageCount,c#,EF,item,Key,CustomerId
来源: https://www.cnblogs.com/printertool/p/16555149.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有