如何让聚合执行的更快???

贾桂权 2010-01-19 02:34:56

;with tb as(--这个括号中的内容执行很快,5ms左右
select
a.salesorderid,.... --20个左右的字段
from a
inner join b WITH ( NOLOCK ) on b.salesorderid = a.salesorderid
inner join c WITH ( NOLOCK ) on c.salesorderid = a.salesorderid
inner join d WITH ( NOLOCK ) on d.airbookingitemid = c.airbookingitemid
inner join ....还有7,8个连接表 )

select distinct top 10000
tb.*,
--以下三个字段执行非常慢,大概需要2000ms左右
( select sum(pl1.salesprice)
from pl1 WITH ( NOLOCK )
inner join it1 WITH ( NOLOCK ) on it1.InsuranceTicketID = pl1.itemidentityid
where pl1.salesorderid = tb.salesorderid
and pl1.itemtypeid = 8
and it1.Status in ( 0, 1 )
) as NormalInsurancePrice,

( select isnull(sum(pl2.salesprice), 0)
from pl2 WITH ( NOLOCK )
inner join it2 WITH ( NOLOCK ) on it2.InsuranceTicketID = pl2.itemidentityid
inner join x WITH ( NOLOCK ) on x.InsuranceTicketID = it2.InsuranceTicketID
inner join at WITH ( NOLOCK ) on at.AirTicketID = x.AirTicketID
where at.AirTicketID = tb.AirTicketID
and pl2.itemtypeid = 8
and it2.Status in ( 0, 1 )
) as UniversalInsurancePrice,

( select isnull(count(*), 1)
from ait2 WITH ( NOLOCK )
inner join at2 WITH ( NOLOCK ) on at2.AirTicketID = ait2.AirTicketID
inner join abi2 WITH ( NOLOCK ) on abi2.airbookingitemid = at2.airbookingitemid
and abi2.salesorderid = tb.salesorderid
) as UniversalInsuranceCount
from tb
order by createtime desc,
salesorderid,
airpnrid,
travelername,
airticketid,
startingtime




该加的索引已加。

如何改造才能使那些聚合内容执行的更快?
...全文
258 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
贾桂权 2010-01-25
  • 打赏
  • 举报
回复
还有没有其他的办法?还是老样子。 
Mr_Nice 2010-01-25
  • 打赏
  • 举报
回复
路过,学习...
黄_瓜 2010-01-25
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 jia_guijun 的回复:]
SQL codeselect at.AirTicketID,isnull(sum(pl2.salesprice),0)as UniversalInsurancePricefrom pricelist pl2WITH ( NOLOCK )innerjoin insuranceticket it2WITH ( NOLOCK )on it2.InsuranceTicketID= pl2.itemidentityidinnerjoin AirTicketInsuranceTicketWITH ( NOLOCK )on AirTicketInsuranceTicket.InsuranceTicketID= it2.InsuranceTicketIDinnerjoin AirTicket atWITH ( NOLOCK )on at.AirTicketID= AirTicketInsuranceTicket.AirTicketIDwhere pl2.itemtypeid=8and it2.Statusin (0,1 )groupby at.AirTicketID



[/Quote]

索引查找开销好大呀
贾桂权 2010-01-22
  • 打赏
  • 举报
回复
.
lsd123 2010-01-19
  • 打赏
  • 举报
回复
.
clxsl_huang 2010-01-19
  • 打赏
  • 举报
回复
纯学习
SQL77 2010-01-19
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 garnett_kg 的回复:]
1).


select    at.AirTicketID,isnull(sum(pl2.salesprice), 0) as UniversalInsurancePrice
          from      pricelist pl2 WITH ( NOLOCK )
                    inner join insuranceticket it2 WITH ( NOLOCK ) on it2.InsuranceTicketID = pl2.itemidentityid
                    inner join AirTicketInsuranceTicket WITH ( NOLOCK ) on AirTicketInsuranceTicket.InsuranceTicketID = it2.InsuranceTicketID
                    inner HASH join AirTicket at WITH ( NOLOCK ) on at.AirTicketID = AirTicketInsuranceTicket.AirTicketID
          where    pl2.itemtypeid = 8
                    and it2.Status in ( 0, 1 )
          group by at.AirTicketID

2).
如果 1方法效果不好, DROP 掉 AirTicket.IX_AirTicket 索引.

[/Quote]
一个索引查找要花费这么多?
Garnett_KG 2010-01-19
  • 打赏
  • 举报
回复

1).


select at.AirTicketID,isnull(sum(pl2.salesprice), 0) as UniversalInsurancePrice
from pricelist pl2 WITH ( NOLOCK )
inner join insuranceticket it2 WITH ( NOLOCK ) on it2.InsuranceTicketID = pl2.itemidentityid
inner join AirTicketInsuranceTicket WITH ( NOLOCK ) on AirTicketInsuranceTicket.InsuranceTicketID = it2.InsuranceTicketID
inner HASH join AirTicket at WITH ( NOLOCK ) on at.AirTicketID = AirTicketInsuranceTicket.AirTicketID
where pl2.itemtypeid = 8
and it2.Status in ( 0, 1 )
group by at.AirTicketID

2).
如果 1方法效果不好, DROP 掉 AirTicket.IX_AirTicket 索引.
贾桂权 2010-01-19
  • 打赏
  • 举报
回复

select    at.AirTicketID,isnull(sum(pl2.salesprice), 0) as UniversalInsurancePrice
from pricelist pl2 WITH ( NOLOCK )
inner join insuranceticket it2 WITH ( NOLOCK ) on it2.InsuranceTicketID = pl2.itemidentityid
inner join AirTicketInsuranceTicket WITH ( NOLOCK ) on AirTicketInsuranceTicket.InsuranceTicketID = it2.InsuranceTicketID
inner join AirTicket at WITH ( NOLOCK ) on at.AirTicketID = AirTicketInsuranceTicket.AirTicketID
where pl2.itemtypeid = 8
and it2.Status in ( 0, 1 )
group by at.AirTicketID


[img=http://hi.csdn.net/attachment/201001/19/19210_1263887888kJ8S.jpg]怎么帖图?我的博客照片不能上传。[/img]
SQL77 2010-01-19
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 garnett_kg 的回复:]
ok.没折了。
不帖执行计划,仅从语句上看能优化的地方只能到此为止了。

帖执行计划 & 索引情况
[/Quote]
继续跟着学习,顺便实践一下学的索引知识
SQL77 2010-01-19
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 jia_guijun 的回复:]
引用 15 楼 sql77 的回复:
引用 14 楼 jia_guijun 的回复:
一样的,主要是那些聚合时消耗较大,tb内容基本不占资源。

参数替换呢,具体看下执行计划看看哪个比较多


你那个参数替换只能应用到获取1条记录的语句中。
[/Quote]
哦,弄错,呵呵,有跟TB连接
Garnett_KG 2010-01-19
  • 打赏
  • 举报
回复
ok.没折了。
不帖执行计划,仅从语句上看能优化的地方只能到此为止了。

帖执行计划 & 索引情况
贾桂权 2010-01-19
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 garnett_kg 的回复:]
那换另外一种方案

先做聚合,然後再跟 tb 做 join .
.....
from tb
    INNER JOIN
        (
        select  p11.salesorderid, NormalInsurancePrice=sum(pl1.salesprice)
          from      pl1 WITH ( NOLOCK )
                    inner join it1 WITH ( NOLOCK ) on it1.InsuranceTicketID = pl1.itemidentityid
          where   
                    and pl1.itemtypeid = 8
                    and it1.Status in ( 0, 1 )
          GROUP BY p11.salesorderid
        ) normal
      ON normal.salesorderid = tb.salesorderid
.....

[/Quote]


这个我自己试过,效率同样。
贾桂权 2010-01-19
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 sql77 的回复:]
引用 14 楼 jia_guijun 的回复:
一样的,主要是那些聚合时消耗较大,tb内容基本不占资源。

参数替换呢,具体看下执行计划看看哪个比较多
[/Quote]

你那个参数替换只能应用到获取1条记录的语句中。
Garnett_KG 2010-01-19
  • 打赏
  • 举报
回复
那换另外一种方案

先做聚合,然後再跟 tb 做 join .
.....
from tb
INNER JOIN
(
select p11.salesorderid, NormalInsurancePrice=sum(pl1.salesprice)
from pl1 WITH ( NOLOCK )
inner join it1 WITH ( NOLOCK ) on it1.InsuranceTicketID = pl1.itemidentityid
where
and pl1.itemtypeid = 8
and it1.Status in ( 0, 1 )
GROUP BY p11.salesorderid
) normal
ON normal.salesorderid = tb.salesorderid
.....
SQL77 2010-01-19
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 jia_guijun 的回复:]
一样的,主要是那些聚合时消耗较大,tb内容基本不占资源。
[/Quote]
参数替换呢,具体看下执行计划看看哪个比较多
贾桂权 2010-01-19
  • 打赏
  • 举报
回复
一样的,主要是那些聚合时消耗较大,tb内容基本不占资源。
Garnett_KG 2010-01-19
  • 打赏
  • 举报
回复
改用#方案呢?
贾桂权 2010-01-19
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 garnett_kg 的回复:]
try it:

。。。。。
[/Quote]


效率未提高。
Garnett_KG 2010-01-19
  • 打赏
  • 举报
回复

--方案二
select
a.salesorderid,.... --20个左右的字段
into #tb
from a
inner join b WITH ( NOLOCK ) on b.salesorderid = a.salesorderid
inner join c WITH ( NOLOCK ) on c.salesorderid = a.salesorderid
inner join d WITH ( NOLOCK ) on d.airbookingitemid = c.airbookingitemid
inner join ....还有7,8个连接表 )

CREATE CLUSTERED INDEX CI_salesorderid ON #tb(salesorderid,AirTicketID)


SELECT DISTINCT TOP 10000
tb.*,
--以下三个字段执行非常慢,大概需要2000ms左右
Normal.NormalInsurancePrice,
Universal.UniversalInsurancePrice,
UniversalInsurance.UniversalInsuranceCount
from #tb tb
CROSS APPLY
( select NormalInsurancePrice=sum(pl1.salesprice)
from pl1 WITH ( NOLOCK )
inner join it1 WITH ( NOLOCK ) on it1.InsuranceTicketID = pl1.itemidentityid
where pl1.salesorderid = tb.salesorderid
and pl1.itemtypeid = 8
and it1.Status in ( 0, 1 )
) as Normal
CROSS APPLY
( select UniversalInsurancePrice=isnull(sum(pl2.salesprice), 0)
from pl2 WITH ( NOLOCK )
inner join it2 WITH ( NOLOCK ) on it2.InsuranceTicketID = pl2.itemidentityid
inner join x WITH ( NOLOCK ) on x.InsuranceTicketID = it2.InsuranceTicketID
inner join at WITH ( NOLOCK ) on at.AirTicketID = x.AirTicketID
where at.AirTicketID = tb.AirTicketID
and pl2.itemtypeid = 8
and it2.Status in ( 0, 1 )
) as Universal
CROSS APPLY
( select UniversalInsuranceCount=isnull(count(*), 1)
from ait2 WITH ( NOLOCK )
inner join at2 WITH ( NOLOCK ) on at2.AirTicketID = ait2.AirTicketID
inner join abi2 WITH ( NOLOCK ) on abi2.airbookingitemid = at2.airbookingitemid
and abi2.salesorderid = tb.salesorderid
) as UniversalInsurance
order by createtime desc,
salesorderid,
airpnrid,
travelername,
airticketid,
startingtime
加载更多回复(10)

22,298

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧