[问题记录] SQL语句在代码中超时,但是在SMSS中执行时很快
最终解决方法:将代码中的SQL语句改成存储过程来执行。
---------------------------------------------------------------------------------
原来的SQL语句为了防止SQL注入,使用的是参数化SQL语句,但是不知道为什么把SQL语句拿到SMSS中执行就没有问题,只在代码中超时。
一开始是直接把参数替换成了参数值,所以在SMSS中执行顺利。
举个例子,就是把带参数的SQL
SELECT * FROM XXXTable WHERE Column1 = @Parameter1 AND ...
改成
SELECT * FROM XXXTable WHERE Column1 = 'Value' AND ...
这样直接跑起来速度很快,看不出问题。
后来一想,可能不对 , 这样模拟不出来。
于是改成这样。
DECLARE @PARAMETTER VARCHAR(100) SET @PARAMETTER = XXX SELECT * FROM XXXTABLE WHERE COLUMN = @PARAMETTER AND ...
这一测,发现速度真的很慢。
在网上找了下,可以在语句末尾加上OPTION(RECOMPILE), 可以提高带参数执行SQL语句的索引效率。
改成如下。
DECLARE @PARAMETTER VARCHAR(100) SET @PARAMETTER = XXX SELECT * FROM XXXTABLE WHERE COLUMN = @PARAMETTER AND ... OPTION(RECOMPILE)
不错,这个执行很快。我还以为解决了,赶紧放到程序的SQL里。结果程序一运行,还是超时了。
继续在网上找,看到说应该在语句前面加上这个。结果还是不行。
SET ARITHABORT ON
当时没想通,怎么其他SQL都没问题,就单单这一个SQL会这样。
实在不知道怎么搞的时候,想想干脆看看语句能不能优化下,认真看了下,发现语句里有个条件是
ColumnX LIKE Concat('%',@ParameterX,'%')
想着干脆随便改下,重新试试SQL能不能在程序里正常运行,就把这句改成
ColumnX = @ParameterX
结果发现,程序没超时了,这才发现问题可能是来自 like '%XXX%' .
可是奇怪了,怎么SMSS还能正常跑呢?
本想着直接把like改掉吧,可是从业务的角度看,这样做不行。
网上一看,又是些创建全文索引(CREATE FULLTEXT INDEX),或是 like 'XXX%' OR like '%XXX'. 一是嫌麻烦,二是感觉不行。
又想了下,既然在SMSS能正常跑,那我干脆把SQL放在SMSS里就好了。
于是写了存储过程,程序在代码中执行存储过程。
后来测试了下,一切正常,程序执行速度与SMSS执行速度持平。
至此,告一段落了。
虽说问题解决了,不过有些东西还是没搞清楚,这个看看以后能不能搞懂了。