[问题记录] SQL语句在代码中超时,但是在SMSS中执行时很快

发布时间 2023-07-04 08:29:18作者: WikiChen

最终解决方法:将代码中的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执行速度持平。

至此,告一段落了。

虽说问题解决了,不过有些东西还是没搞清楚,这个看看以后能不能搞懂了。