事情是这样的, 我的一个存储过程里有这么一段代码:
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
------解决方案--------------------
快捷键:ctrl+m这个是能显示实际的执行计划。
要更新统计信息:
update statistics 表
要强制join:
select *
from a
inner hash join b
on a.xx = b.xx
当然这个hash也可以是loop,或者merge
------解决方案--------------------
做优化的时候,
就是把自己当成QO,如果你是QO你会选择哪个查询计划?你为什么会选择那个计划?凭哪些因素?
如果最后的结果证明你选错的时候,那你就问自己为什么会选错了,错在哪里?
是不是在计算某个子树的COST用了不准备的统计信息,是不是缺少某个索引什么的.....,这些都可以看得出来。
恩 我对oracle比较了解点 虽然用了sqlserver7,8年了从来没好好研究过他。。 oracle里的统计信息、NL连接 hash连接 执行计划都搞得比较明白了 就是在sqlserver里不知道怎么看统计信息 怎么看执行计划。。 怎么让B表做驱动表和A表做NL连接
现在强制用HASH join , 问题暂时解决了
“sqlserver里不知道怎么看统计信息”
http://technet.microsoft.com/en-us/library/cc966419.aspx
“怎么看执行计划”
set statistics profile on 是很好的一种,比图像计划好的是,前者你可以在论坛中贴出很多重要的统计信息。
“怎么让B表做驱动表和A表做NL连接”
query hint呀
B INNER LOOP JOIN A
------解决方案--------------------
做优化的时候,
就是把自己当成QO,如果你是QO你会选择哪个查询计划?你为什么会选择那个计划?凭哪些因素?
如果最后的结果证明你选错的时候,那你就问自己为什么会选错了,错在哪里?
是不是在计算某个子树的COST用了不准备的统计信息,是不是缺少某个索引什么的.....,这些都可以看得出来。
恩 我对oracle比较了解点 虽然用了sqlserver7,8年了从来没好好研究过他。。 oracle里的统计信息、NL连接 hash连接 执行计划都搞得比较明白了 就是在sqlserver里不知道怎么看统计信息 怎么看执行计划。。 怎么让B表做驱动表和A表做NL连接
现在强制用HASH join , 问题暂时解决了
“sqlserver里不知道怎么看统计信息”
http://technet.microsoft.com/en-us/library/cc966419.aspx
“怎么看执行计划”
set statistics profile on 是很好的一种,比图像计划好的是,前者你可以在论坛中贴出很多重要的统计信息。
“怎么让B表做驱动表和A表做NL连接”
query hint呀
B INNER LOOP JOIN A
oracle里的统计信息有 表的统计信息(行数等信息) 索引的统计信息 , sqlserver里有这样分吗? 如果在sqlserver里想查表的统计信息要用什么命令?
sql server也是一样的,有列的,有索引的统计信息,