复杂查询还是直接写sql吧

今日改了一个linq,为了查询优化。

主要思路是把子查询改为连接查询。

改完后,本地运行是很快的;但是发布到服务器,加上网络时间,就有点不如意了。

所以感觉,非常复杂的查询还是直接用sql写好。

更改前后

更改前是这样的。

            void setPropety(List<SEO_Cust_RechargeModel> _list)
            {
                SEO_Set_MealBusiness sEO_Set_MealBusiness = new SEO_Set_MealBusiness();
                SEO_CustBusiness sEO_CustBusiness = new SEO_CustBusiness();
                //SEO_Cust_ProductBusiness sEO_Cust_ProductBusiness = new SEO_Cust_ProductBusiness();
                var domain = new Seo_Domain.SEO_DomainBusiness().GetIQueryable();
                var keywords = new SEO_KeyWordBusiness().GetIQueryable();
                var newsfeed = new Seo_NewsFeed.SEO_NewsFeedBusiness().GetIQueryable();
                var zengzhibus = new SEO_ZengZhiFwBusiness();
                _list.ForEach(x =>
                {
                    x.SetMeal_Name = sEO_Set_MealBusiness.GetTheData(x.setmeal_id)?.set_meal_name;
                    x.Cust_Nmae = sEO_CustBusiness.GetTheData(x.cust_id)?.user_name;
                    x.domainnum = domain.Where(xx => xx.cust_recharge_id == x.Id).Count();
                    x.keywordnum = keywords.Where(xx => xx.recharge_id == x.Id).Count();
                    x.newsfeednum = newsfeed.Where(xx => xx.recharge_id == x.Id).Count();
                    x.zengzhinum = zengzhibus.GetIQueryable().Count(y => y.recharge_id == x.Id);
                    x.pinpainum = new SEO_PinPai_KeyWordBusiness().GetIQueryable().Where(xx => xx.recharge_id == x.Id).Count();
                    x.SEOUser_Name = Base_UserBusiness.GetTheUser(x.seo_user_id)?.RealName;
                });
            }

更改后是这样的。

            void setPropetyByJoin(List<SEO_Cust_RechargeModel> _list)
            {
                //5个count
                var queryCount = from r in _list
                                 join dm in new SEO_DomainBusiness().GetIQueryable() on r.Id equals dm.cust_recharge_id into dmg
                                 join kw in new SEO_KeyWordBusiness().GetIQueryable() on r.Id equals kw.recharge_id into kwg
                                 join nf in new SEO_NewsFeedBusiness().GetIQueryable() on r.Id equals nf.recharge_id into nfg
                                 join zz in new SEO_ZengZhiFwBusiness().GetIQueryable() on r.Id equals zz.recharge_id into zzg
                                 join pp in new SEO_PinPai_KeyWordBusiness().GetIQueryable() on r.Id equals pp.recharge_id into ppg
                                 select new
                                 {
                                     rId = r.Id,
                                     dmCount = dmg.Count(),
                                     kwCount = kwg.Count(),
                                     nfCount = nfg.Count(),
                                     zzCount = zzg.Count(),
                                     ppCount = ppg.Count(),
                                 };
                var lct = queryCount.ToList();

                //连接其他表
                var queryJoin = from r in _list
                                join c in queryCount.Distinct() on r.Id equals c.rId
                                join sm in new SEO_Set_MealBusiness().GetIQueryable() on r.setmeal_id equals sm.Id into rSmG
                                join cst in new SEO_CustBusiness().GetIQueryable() on r.cust_id equals cst.Id into rCstG
                                join bu in new Base_UserBusiness().GetIQueryable() on r.seo_user_id equals bu.UserId into rBuG
                                join pr in new SEO_ProductBusiness().GetIQueryable() on r.product_id equals pr.Id into rPrG
                                from rSm in rSmG.DefaultIfEmpty()
                                from rCst in rCstG.DefaultIfEmpty()
                                from rBu in rBuG.DefaultIfEmpty()
                                from rPr in rPrG.DefaultIfEmpty()
                                select new
                                {
                                    r = r,
                                    c = c,
                                    agent_id = rCst?.agent_id ?? "",
                                    xs_user_id = rCst?.xs_user_id ?? "",
                                    SetMeal_Name = rSm == null ? "" : rSm.set_meal_name,
                                    Cust_Nmae = rCst == null ? "" : rCst.user_name,
                                    SEOUser_Name = rBu == null ? "" : rBu.RealName,
                                    pro_name = rPr == null ? "-" : rPr.pro_name,
                                    aftersale_user_id = rCst.aftersale_user_id, 
                                };

                //二次连接的
                var queryJoin2 = from m in queryJoin
                                 join ag in new SEO_AgentBusiness().GetIQueryable() on m.agent_id equals ag.Id into mAgG
                                 join buAfter in new Base_UserBusiness().GetIQueryable() on m.aftersale_user_id equals buAfter.UserId into mBuAfterG
                                 from mAg in mAgG.DefaultIfEmpty()
                                 from mBuAfter in mBuAfterG.DefaultIfEmpty()
                                 select new
                                 {
                                     r = m.r,
                                     c = m.c,
                                     agent_id = m.agent_id,
                                     xs_user_id = m.xs_user_id,
                                     SetMeal_Name = m.SetMeal_Name,
                                     Cust_Nmae = m.Cust_Nmae,
                                     SEOUser_Name = m.SEOUser_Name,
                                     pro_name = m.pro_name,
                                     SEOAfterSale_Name = m.aftersale_user_id.IsNullOrEmpty() || m.aftersale_user_id == "0" ?
                                                        "-" :
                                                        mBuAfter?.RealName??"-",
                                     SEOSale_Name = (m.xs_user_id.IsNullOrEmpty() || m.xs_user_id == "0") ? 
                                                    mAg?.inst_value??"-" : 
                                                    m.SEOUser_Name,
                                 }; 

                //循环赋值
                queryJoin2.Select(m =>
                {
                    //Count的
                    m.r.domainnum = m.c.dmCount;
                    m.r.keywordnum = m.c.kwCount;
                    m.r.newsfeednum = m.c.nfCount;
                    m.r.zengzhinum = m.c.zzCount;
                    m.r.pinpainum = m.c.ppCount;
                    //单个属性
                    m.r.SetMeal_Name = m.SetMeal_Name;
                    m.r.Cust_Nmae = m.Cust_Nmae;
                    m.r.SEOUser_Name = m.SEOUser_Name;
                    m.r.pro_name = m.pro_name;
                    m.r.SEOAfterSale_Name = m.SEOAfterSale_Name;
                    m.r.SEOSale_Name = m.SEOSale_Name; 
                    return 1;
                }).ToList();
            }

可以明显的看到:

子查询看起来简单;但是运行效率低。

连接查询编写起来复杂,特别是用linq写,就更复杂了。

还有第二波问题:

改完一波,我才发现,原来的作者在ViewModel里弄了一些有get访问器的属性。

而有几个get访问器,在里面操作了数据库。也相当于子查询。

于是又改了一波。

另外重要的

另外重要的,感觉是数据表的设计。

因为,感觉,虽然不知道是什么业务;有些字段的获取应该不用关联这么多表吧?应该是可以简化的。

 

 

posted @ 2024-08-08 17:37  法宝  阅读(8)  评论(0编辑  收藏  举报