碰到一个奇怪的问题,在一个存储过程里面,有一个where条件
and closingMonth like '%2018-08%'
and closingMonth like '%'+@closingMonth+'%'
其中变量 @closingMonth 的值就是 2018-08
当我这个值以 @closingMonth 从存储过程外部传进来的话,就很慢很慢才能查出来
当我在那个 where 条件 like 后面写死这个 2018-08 就很快能查出来
所以,按道理来说不都是 like '%2018-08%' 么?为什么会这样呢?
求解答
@closingMonth
定义的类型是什么?
nvarchar(50)
杜杜大,感谢每次我提问你都是第一个回答。我的 @closingMonth 的数据类型是 nvarchar(50),是存储过程的入参。
@LoveCoder: 建议在 SQL Server 的查询窗口传参执行存储过程,然后看一下执行计划
@dudu:
杜杜大,以上是我的执行计划。
我在一个dba群里面询问,得到的解答大概是:
因为执行计划是由语句编译时选择的
而不是边执行边选择
你使用变量就慢,极可能的原因是因为 "参数预估" 的值,与你传入的值出入较大造成
他让我更新统计信息,然后我更新了统计信息,还是没用,然后他现在还没回我,之前他还说了,让我指定索引什么的,但是他说那不是常规的手段,一般是更新统计信息来解决这个问题。我对数据库研究不是很深,只会写sql,你能帮我一起看看吗
@LoveCoder: closingMonth
字段有没有加索引?
@dudu: 有索引。
但是like 的话,索引好像不起作用吧?
@LoveCoder: 建议把索引删除看看效果
@LoveCoder: 另外建议手动执行存储过程时开启set statistics io on
看一下IO情况
@LoveCoder: 有一个方法应该可以解决问题,将sql语句放在字符串中,然后用exec
执行
@dudu: 这个存储过程太长,不是很适合这样去解决。
还有其他办法吗
@LoveCoder: 试试
SELECT 1
WHERE CHARINDEX('改变', '代码改变世界') > 0
对应你的应用场景
SELECT ...
WHERE CHARINDEX(@closingMonth, closingMonth) > 0
@dudu: 这个方法是不是太偏门啊?我想知道它造成的原因,从根本上去解决。
这个应该是参数嗅探问题,你要对比看看两者执行计划嵌套循环的次数。
兄弟,DBA群里面有人提到参数嗅探这个问题,这种大概解决的思路是?