一个怪异的现象,语句特别慢,帮分析原因

hlj321 2012-12-08 04:29:58
下面是语句,此语句执行了超过了30分钟,
  SELECT    *
FROM CSKH ccc
INNER JOIN ( SELECT a.fgsid ,
SUM(a.je) AS je ,
COUNT(*) AS kll ,
SUM(bs) AS bs ,
SUM(sl) AS sl ,
SUM(ml) AS ml
FROM ( SELECT fgsid ,
lsh ,
SUM(je) AS je ,
SUM(sl) AS sl ,
COUNT(*) AS bs ,
SUM(ml) AS ml
FROM fgs_xsd (NOLOCK)
WHERE kdrq BETWEEN '2012-12-01'
AND DATEADD(day, 1, '2012-12-11')
GROUP BY fgsid ,
lsh
) a
GROUP BY a.fgsid
) b
ON ccc.id = b.fgsid
...全文
172 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
發糞塗牆 2012-12-09
  • 打赏
  • 举报
回复
瞄了一下执行计划,初步给点建议: 1、每次执行之前,先执行一下DBCC FREEPROCCACHE。这样避免缓存执行计划的影响。 2、第一个语句,主要慢在排序,而这个排序是因为group by引起的,具体是哪个group by最后点开那个图标看看。而你第二句语句,耗费在哈希连接,而在非常大数据量的时候,且没有办法加索引或者where条件的时候,hash处理是最快的。如果你的数据量很大(看上去的确挺大)。应该是很快的。同时你第二句是“索引查找”,在大部分情况下会比索引扫描、表扫描块的多。由于你那些箭头很粗,估计也有个几十万甚至百万的数据。这时候扫描和查找的开销的非常大。 3、你的where条件其实就是查找1天的数据,所以如果有索引,筛选性应该还是很高的。而你第一句的筛选性就很低,箭头很粗,而且一直延续到比较后面的地方。也就是一直在处理比较大的数据量。但是第二个语句,箭头很快就降下来了。也就是后面处理的数据量相对来说少很多。
以学习为目的 2012-12-08
  • 打赏
  • 举报
回复
其实这个解释,看执行计划更加直观
以学习为目的 2012-12-08
  • 打赏
  • 举报
回复
第一种联合查询inner join联合对象又是嵌套查询,做对应复杂些。
hlj321 2012-12-08
  • 打赏
  • 举报
回复
第一个语句中的*号正常应当是 cskh.DWBH AS 门店编号 , cskh.mc AS 门店 , ISNULL(b.je, 0) AS 销售额 , ISNULL(b.ml, 0) AS 毛利 , ( CASE WHEN ISNULL(b.je, 0) = 0 THEN 1 ELSE ISNULL(b.ml, 0) / ISNULL(b.je, 0) END ) AS 毛利率 , b.kll AS 客流量 , ISNULL(ROUND(b.je / b.kll, 2), 0) AS 客单价 , b.sl AS 数量 , ( CASE WHEN ISNULL(b.sl, 0) = 0 THEN 0 ELSE b.je / b.sl END ) AS 品单价 , b.bs AS 销售笔数
zoffor 2012-12-08
  • 打赏
  • 举报
回复
看不大懂。 是因为重用了之前的部分缓存数据和执行计划吧
hlj321 2012-12-08
  • 打赏
  • 举报
回复
CSKH表共19条记录,ID是主键
hlj321 2012-12-08
  • 打赏
  • 举报
回复
CREATE NONCLUSTERED INDEX idx_fgs_xsd_kdrq1
ON [dbo].[fgs_XSD] ([KDRQ])
INCLUDE ([FGSID],[LSH],[SL],[JE],[ML])
hlj321 2012-12-08
  • 打赏
  • 举报
回复
我换一种方法,此种方法1秒都用不到就完成了
SELECT a.fgsid , (select  mc from CSKH where CSKH.id = a.fgsid ) as mc ,
SUM(a.je) AS je ,
COUNT(*) AS kll ,
SUM(bs) AS bs ,
SUM(sl) AS sl ,
SUM(ml) AS ml INTO #abcd
FROM ( SELECT fgsid ,
lsh ,
SUM(je) AS je ,
SUM(sl) AS sl ,
COUNT(*) AS bs ,
SUM(ml) AS ml
FROM fgs_xsd (NOLOCK)
WHERE kdrq BETWEEN '2012-12-01'
AND DATEADD(day, 1, '2012-12-11')
GROUP BY fgsid ,
lsh
) a
GROUP BY a.fgsid

下图是这个语句实际执行计划
zywhao 2012-12-08
  • 打赏
  • 举报
回复
关注一下
hlj321 2012-12-08
  • 打赏
  • 举报
回复
下图为实际执行计划

22,209

社区成员

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

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