查询语句太慢帮忙看看这个语句能否优化

liusaabb 2014-05-29 08:55:45
现有一个报表 需要从存储过程中获取数据,但速度比较慢。查看执行计划后 发现是存储过程中有一个语句是导致报表查询慢的主要原因
select  c.fitemid,c.FNumber 物料编号, c.FName 物料名称,isnull(c.FModel,'''') 规格型号    
,isnull(d.FName,'''') 单位,isnull(a.FBatchNo,'''') fbatchno,b.fname,a.fqty,
isnull((select top 1 b1.FAuxPrice from ICStockBill a1
inner join ICStockBillEntry b1 on a1.FInterID=b1.FInterID
where FTranType in(1,2,5,10,40) and a1.FCheckerID>0 and b1.fitemid=a.fitemid and b1.fbatchno=a.fbatchno
order by a1.fcheckdate desc),0) 单价
from ICInventory a inner join t_Stock b on a.FStockID=b.FItemID
inner join t_ICItem c on a.FItemID=c.FItemID
inner join t_MeasureUnit d on c.FStoreUnitID=d.FMeasureUnitID

发现是子查询的问题,可否能修改一下
具体消耗如下
(34358 行受影响)
表 'ICStockBill'。扫描计数 930615,逻辑读取 5586813 次,物理读取 26614 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'ICStockBillEntry'。扫描计数 33937,逻辑读取 106586 次,物理读取 3579 次,预读 1184 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'ICInventory'。扫描计数 1,逻辑读取 462 次,物理读取 3 次,预读 458 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 't_ICItemBase'。扫描计数 1,逻辑读取 803 次,物理读取 3 次,预读 800 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 't_ICItemCore'。扫描计数 1,逻辑读取 1199 次,物理读取 3 次,预读 1197 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 't_MeasureUnit'。扫描计数 1,逻辑读取 5 次,物理读取 1 次,预读 3 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 't_Stock'。扫描计数 1,逻辑读取 2 次,物理读取 1 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次
...全文
206 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
Q315054403 2014-05-29
  • 打赏
  • 举报
回复
若没看错,这是KD APP 必须根据数据结构着手,单纯看SQL抽象了点
xdashewan 2014-05-29
  • 打赏
  • 举报
回复
我觉得还是要在键查找上做文章 参考下版主的文章http://blog.csdn.net/dba_huangzj/article/details/8688014
liusaabb 2014-05-29
  • 打赏
  • 举报
回复
引用 3 楼 fredrickhu 的回复:
将这个子查询CROSS APPLY在最后试试

一样的
liusaabb 2014-05-29
  • 打赏
  • 举报
回复
引用 3 楼 fredrickhu 的回复:
将这个子查询CROSS APPLY在最后试试
改成outer apply 貌似快一点 我先清除缓存 重新执行对比看看
liusaabb 2014-05-29
  • 打赏
  • 举报
回复
之前想过把子查询 修改成临时表,但是要取每个物料的最后一次入库审核时候的单价,我想这个必然要用逐条获取数据单价,一样的很慢 现在是否把键查找这里显示的这个表ICStockBill加个include索引。因为是K3系统,这个表中索引之前建立了很多
--小F-- 2014-05-29
  • 打赏
  • 举报
回复
将这个子查询CROSS APPLY在最后试试
---涛声依旧--- 2014-05-29
  • 打赏
  • 举报
回复
这段(select top 1 b1.FAuxPrice from ICStockBill a1 inner join ICStockBillEntry b1 on a1.FInterID=b1.FInterID where FTranType in(1,2,5,10,40) and a1.FCheckerID>0 and b1.fitemid=a.fitemid and b1.fbatchno=a.fbatchno order by a1.fcheckdate desc) 建议写成视图view,查询最近进料的单价(只须物料编号、批号、单价) 这个视图再与上面的关联查询,速度肯定快了
liusaabb 2014-05-29
  • 打赏
  • 举报
回复
这个是截取的实际执行计划中一部分
發糞塗牆 2014-05-29
  • 打赏
  • 举报
回复
max的时候group by 审核时间和物料单价,跟top1一样,别说的那么“必然”
liusaabb 2014-05-29
  • 打赏
  • 举报
回复
引用 9 楼 DBA_Huangzj 的回复:
红字部分可以考虑用join或者select max来试试 SELECT c.fitemid , c.FNumber 物料编号 , c.FName 物料名称 , ISNULL(c.FModel, '''') 规格型号 , ISNULL(d.FName, '''') 单位 , ISNULL(a.FBatchNo, '''') fbatchno , b.fname , a.fqty , ISNULL(( SELECT TOP 1 b1.FAuxPrice FROM ICStockBill a1 INNER JOIN ICStockBillEntry b1 ON a1.FInterID = b1.FInterID WHERE FTranType IN ( 1, 2, 5, 10, 40 ) AND a1.FCheckerID > 0 AND b1.fitemid = a.fitemid AND b1.fbatchno = a.fbatchno ORDER BY a1.fcheckdate DESC ), 0) 单价 FROM ICInventory a INNER JOIN t_Stock b ON a.FStockID = b.FItemID INNER JOIN t_ICItem c ON a.FItemID = c.FItemID INNER JOIN t_MeasureUnit d ON c.FStoreUnitID = d.FMeasureUnitID
top 1 那里最主要是考虑到有重复的审核时间和物料单价 那么就只取top 1 如果用jion 或者max 那么查出来的数据就必然会多某些条
發糞塗牆 2014-05-29
  • 打赏
  • 举报
回复
红字部分可以考虑用join或者select max来试试 SELECT c.fitemid , c.FNumber 物料编号 , c.FName 物料名称 , ISNULL(c.FModel, '''') 规格型号 , ISNULL(d.FName, '''') 单位 , ISNULL(a.FBatchNo, '''') fbatchno , b.fname , a.fqty , ISNULL(( SELECT TOP 1 b1.FAuxPrice FROM ICStockBill a1 INNER JOIN ICStockBillEntry b1 ON a1.FInterID = b1.FInterID WHERE FTranType IN ( 1, 2, 5, 10, 40 ) AND a1.FCheckerID > 0 AND b1.fitemid = a.fitemid AND b1.fbatchno = a.fbatchno ORDER BY a1.fcheckdate DESC ), 0) 单价 FROM ICInventory a INNER JOIN t_Stock b ON a.FStockID = b.FItemID INNER JOIN t_ICItem c ON a.FItemID = c.FItemID INNER JOIN t_MeasureUnit d ON c.FStoreUnitID = d.FMeasureUnitID
shinger126 2014-05-29
  • 打赏
  • 举报
回复
既然是存储过程,为什么不用临时表来解决。使用临时表存储计算出来的最后进价,然后再关联。

27,579

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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