更快的SQL查询超过200万行

时间:2014-09-19 14:49:03

标签: sql sql-server

我有一堆表,我正在加入搜索查询。此查询允许多个可选参数。但它正在搜索的主表(T_AS400_BLRPIN00)有超过200万行。

当我运行执行计划时,大部分时间都花费在非聚集索引扫描上。

表格(T_AS400_BLRPIN00)有38列,我不会在这里列出所有列(除非你认为有必要),但有些关键字段是:

INSPASER (int, null) -- Part of the old key  
INSPIND (varchar(1), null) -- The other part of the old key  
T_AS400_BLRPIN00_ID (PK, int, not null) -- The new key  

使用的索引如下所示:

CREATE NONCLUSTERED INDEX [IX01_T_AS400_BLRPIN00] 
ON [dbo].[T_AS400_BLRPIN00] 
(
    [INSPASER] ASC,
    [INSPIND] ASC
)

我的存储过程/查询会像这样搜索表:

FROM
    dbo.T_AS400_BLRPIN00 AS Insp
LEFT JOIN 
    dbo.T_AS400_BLRPEQP00 AS Eqp ON Insp.T_AS400_BLRPEQP00_ID = Eqp.T_AS400_BLRPEQP00_ID
WHERE
    (@pint_INSPASER=0 OR Insp.INSPASER = @pint_INSPASER)
    AND 
    (ISNULL(INSPIND,'') like '%' + @pstr_INSPIND + '%')

我不喜欢用varchar搜索这么大的桌子,但是现在我们需要这种能力。有时候@pstr_INSPIND是一个空字符串(''),因为它们没有按字母搜索,有时它只是一个字符()。

执行计划显示索引扫描(非聚集)占63%,然后密钥查找的嵌套循环(内部联接)占36%。

我有更好的方法来设计这个吗?

3 个答案:

答案 0 :(得分:1)

尝试更改此

  WHERE

(@pint_INSPASER=0 OR Insp.INSPASER = @pint_INSPASER)
AND 
(ISNULL(INSPIND,'') like '%' + @pstr_INSPIND + '%')

到这个

  WHERE
    (@pint_INSPASER=0 OR Insp.INSPASER = @pint_INSPASER)
    AND 
    (INSPIND = @pstr_INSPIND or INSPIND is NULL)

答案 1 :(得分:0)

执行like '%abc%'是致命的 - 你根本就没有使用索引。

因此,您可以通过完全从复合索引中删除它来获得更好的性能。

此外,如果可能,请尝试减少搜索,以便您执行like 'abc%' - 实际上可以使用索引。另外,为什么您在%列上使用varchar(1)

答案 2 :(得分:0)

“喜欢”很糟糕。此外,该变量(@pstr_INSPIND)中的内容是什么? Parameter sniffing?

您的统计数据是什么样的?返回估计的vs实际行数?

不确定如何填充@pstr_INSPIND,但您可能对sqlinjection开放。