日期:2014-05-16  浏览次数:20793 次

有懂优化器的统计信息的吗? 有一个问题不知道怎么解决
本帖最后由 wqrz 于 2014-03-06 13:35:27 编辑

事情是这样的,  我的一个存储过程里有这么一段代码:

   update a set a.cuks=isnull(a.cuks,0)+isnull(b.cuks,0) from ##tmptiaozkcdp a 
 join (select gfrom,code,colorid,xsize,sum(amount) as cuks from g_billd_xs_pos d inner join g_billm_xs_pos m on d.scripno=m.scripno
where (ioflag=6  ) and gfrom=@shopid and iodate>@iodate   group by gfrom,code,colorid,xsize) b
on a.n_leix=1 and a.shopid=b.gfrom and a.code=b.code and a.colorid=b.colorid  and a.xsize=b.xsize

早上客户反映执行这个存储过程的时候卡住了, 几分钟都不动,   然后我看了看   估计是优化器的执行计划错了,   于是加了HINTS , 把连接改成Inner HASH join  , 这个存储过程顺利几秒跑完

 ##tmptiaozkcdp 3000多行    ,  b数据集33行,   请问怎么改成NL连接?

问题2:  这个执行计划是统计信息错了导致的吗?   表的统计信息我看了看都是空的? 这是怎么回事?
问题3: 临时表建立完插入数据后,  sqlserver应该不会收集统计信息吧?  如果没收集那执行计划怎么保证是正确的?
(其实我感觉收集了才对。。)

 
------解决方案--------------------
NL连接是啥?
问题2:看执行计划才知道。有些统计信息需要手动创建,另外你看看你的库是否开启了自动创建和更新统计信息。
问题3:会收集,表变量的话就只有1、0这两种。
------解决方案--------------------
http://blog.csdn.net/fredrickhu/article/details/5166750
------解决方案--------------------
其实你可以查到QO为什么选择nested Loop Join而不是HASH JOIN。
因为QO认为nested Loop Join的COST比HASH JOIN小,
那为什么QO认为nested Loop Join的COST比HASH JOIN小呢?
因为COST是所有operator等的集合,
然后你去从计划中看一下那个total的COST是怎么计算出来的,
用setstatistics profile on来CHECK。

也可以参考一下下面帖子的46楼
http://bbs.csdn.net/topics/390657642
------解决方案--------------------
引用:
Quote: 引用:

做优化的时候,
就是把自己当成QO,如果你是QO你会选择哪个查询计划?你为什么会选择那个计划?凭哪些因素?
如果最后的结果证明你选错的时候,那你就问自己为什么会选错了,错在哪里?
是不是在计算某个子树的COST用了不准备的统计信息,是不是缺少某个索引什么的.....,这些都可以看得出来。


恩  我对oracle比较了解点   虽然用了sqlserver7,8年了从来没好好研究过他。。   oracle里的统计信息、NL连接 hash连接 执行计划都搞得比较明白了   就是在sqlserver里不知道怎么看统计信息  怎么看执行计划。。  怎么让B表做驱动表和A表做NL连接    

 现在强制用HASH join ,  问题暂时解决了   


快捷键:ctrl+m这个是能显示实际的执行计划。

要更新统计信息:
update statistics 表

要强制join:
select *
from a
inner hash join b 
             on a.xx = b.xx

当然这个hash也可以是loop,或者merge
------解决方案--------------------
引用:
Quote: 引用:

做优化的时候,
就是把自己当成QO,如果你是QO你会选择哪个查询计划?你为什么会选择那个计划?凭哪些因素?
如果最后的结果证明你选错的时候,那你就问自己为什么会选错了,错在哪里?
是不是在计算某个子树的COST用了不准备的统计信息,是不是缺少某个索引什么的.....,这些都可以看得出来。


恩  我对oracle比较了解点   虽然用了sqlserver7,8年了从来没好好研究过他。。   oracle里的统计信息、NL连接 hash连接 执行计划都搞得比较明白了   就是在sqlserver里不知道怎么看统计信息  怎么看执行计划。。  怎么让B表做驱动表和A表做NL连接    

 现在强制用HASH join ,  问题暂时解决了   

“sqlserver里不知道怎么看统计信息”
h