select shop_no,store_no,add_no,barcode,[size],store_qty_amt,store_wgt_amt into #temp from tb where id in (select MAX(id) from tb where datediff(day,bill_date,@datemax)>=0 group by bill_no,size )
这个语句是存储过程中间的一段,有这段的话,查询时间多几十秒,tb表里面只有一万多条数据,日期过滤之后只有几千条。数据库是sql2008,操作系统win server 2008,分组字段已经加了索引。单独执行这条语句速度也快,存储过程中屏蔽这段速度也快。
where datediff(day,bill_date,@datemax)>=0 都是这个的错。
不要where中对字段进行运算
那请问要取某个日期之前,分组之后id最大的记录怎么写呢。cte我已经使用过了,没有效果。
where datediff(day,bill_date,@datemax)>=0
可以修改为Where bill_date<=@PreviousDay and biil_Date>=@NextDay
@PreviousDay 和@NextDay可以事先计算好。
简单优化点: in ,where之后的函数。
然后看了下你的存储过程,你可以尝试下用row_number加partition by 来进行查询。
cte试过了,还是慢。
@清海扬波: 这些和CTE无关,CTE对你这个基本没提升。
@幻天芒: cte就是用的row_number加partiton by
@清海扬波: 你还是直接贴代码吧,如果你要在cte中写row_number那也没啥。
在我的理解中,你的需求用了row_number之后,根本就不会有in之后的子查询了。所以直接把性能提高了。
@幻天芒:
select * from ( select *,rownum = row_number() over (partition by bill_no+size order by id desc) from tb where bill_date>@datemax ) as t where t.rownum = 1 类似这样是过程,这段代码应该跑不起来...可以当伪代码看~
换成 exec (@sqlstr) 这种形式执行一下
select shop_no,store_no,add_no,barcode,[size],store_qty_amt,store_wgt_amt from (
select id,shop_no,store_no,add_no,barcode,[size],store_qty_amt,store_wgt_amt,max(id)over(partition by bill_no,size) as MAXid
from tb
where datediff(day,bill_date,@datemax)>=0) as A
where A.id=A.MAXid
这个用row_number()效率更好一些。
select shop_no,store_no,add_no,barcode,[size],store_qty_amt,store_wgt_amt into #temp from ( select shop_no,store_no,add_no,barcode,[size],store_qty_amt,store_wgt_amt,row_number() over(partition by bill_no,size order by id desc) as rId from tb where datediff(day,bill_date,@datemax)>=0 ) as a where rId=1