我有一个sql server存储过程,在服务器上速度非常快,但在其他服务器上速度太慢。

时间:2018-05-08 15:11:03

标签: sql sql-server

我在服务器上运行良好,但在其他数据库(不同的服务器)中,相同的sp运行速度太慢。我知道问题出在哪里,但我找不到为什么它在那里太慢的原因。在我的服务器中,我在主表(客户端表)中有大约2000行,但在另一个中,我有大约7000行。我知道这不是那么多,但在这种情况下,因为这个sp正在搜索一个单词几个字段可能比常规字段慢。你们有些人可以给我一些建议吗?我确实试过一个非群集的索引。 提前致谢

            INSERT INTO @varTable
                select distinct C.id from client C
                    INNER JOIN place pl ON pl.plid = C.id
                    LEFT OUTER JOIN country ctr ON ctr.nr = pl.country
                    LEFT OUTER JOIN person per ON per.id = C.id
                    LEFT OUTER JOIN property pr ON pr.id = C.id
                        WHERE 
                        (           
                                (NOT PR.VALUE IS NULL AND PR.VALUE LIKE '%' + @varSearch  + '%')
                                OR (pl.pl_a_name LIKE '%' + @FIRST_WORD + '%')
                                OR (NOT pl.add1 IS NULL AND pl.add1 LIKE '%' + @varSearch + '%')
                                OR (NOT pl.add2 IS NULL AND pl.add2 LIKE '%' + @varSearch + '%')
                                OR (NOT pl.add3 IS NULL AND pl.add3 LIKE '%' + @varSearch + '%')
                                OR (NOT pl.pcod IS NULL AND pl.pcod LIKE '%' + @varSearch + '%')
                                OR (NOT pl.descr IS NULL AND pl.descr LIKE '%' + @varSearch + '%')
                                OR (NOT pl.phone IS NULL AND pl.phone LIKE '%' + @varSearch + '%')
                                OR (NOT per.ctname IS NULL AND per.ctname LIKE '%' + @varSearch + '%') 
                                OR (NOT per.phone IS NULL AND per.phone LIKE '%' + @varSearch + '%')                                            
                        )
                        AND
                        C.COMPANY = @cia
                        and (@DEPT IS NULL OR C.DEPT in (SELECT nstr FROM iter_charlist_to_table(@DEPT_LIMIT,DEFAULT)))
                        AND ( (@state = 1 AND STATUS != '0') OR (@state <> 1  and STATUS = 'C') )       



            ;WITH DistinctClient AS (
                SELECT DISTINCT C.id, listpos
                    from @varTable C
                    INNER JOIN place pl ON pl.plid = C.id 
                    LEFT OUTER JOIN country ctr ON ctr.nr = pl.country
                    LEFT OUTER JOIN person per ON per.id = C.id
                    LEFT OUTER JOIN property pr ON pr.id = C.id

                    INNER JOIN iter_charlist_to_table(@SEARCH_NAME, ' ') L ON
                        (           
                                (NOT PR.VALUE IS NULL AND PR.VALUE LIKE '%' + L.str  + '%')
                                OR (pl.pl_a_name LIKE '%' + L.str + '%')
                                OR (NOT pl.add1 IS NULL AND pl.add1 LIKE '%' + L.str + '%')
                                OR (NOT pl.add2 IS NULL AND pl.add2 LIKE '%' + L.str + '%')
                                OR (NOT pl.add3 IS NULL AND pl.add3 LIKE '%' + L.str + '%')
                                OR (NOT pl.pcod IS NULL AND pl.pcod LIKE '%' + L.str + '%')
                                OR (NOT pl.descr IS NULL AND pl.descr LIKE '%' + L.str + '%')
                                OR (NOT pl.phone IS NULL AND pl.phone LIKE '%' + L.str + '%')
                                OR (NOT per.ctname IS NULL AND per.ctname LIKE '%' + L.str + '%') 
                                OR (NOT per.phone IS NULL AND per.phone LIKE '%' + L.str + '%')                     
                                OR (NOT per.cellphone IS NULL AND per.cellphone LIKE '%' + L.str + '%')                     
                        )           
            ), 
            DistinctClientsMatchingAllWords AS (
                SELECT TOP 100 DistinctClient.OBJ_NO FROM DistinctClient
                GROUP BY 
                    DistinctClient.id
                HAVING SUM(listpos) = @wsum
            )

            INSERT INTO @tempResults SELECT * FROM DistinctClientsMatchingAllWords
            END

1 个答案:

答案 0 :(得分:0)

您正在使用的第一个CTE作为第二个CTE与GROUP BY / HAVING的嵌套查询没有帮助。尝试临时表而不是第一个CTE,在(id,listpos)上创建一个唯一的聚簇索引,然后引用第二个CTE中的临时表。事实上,看起来不需要第二次CTE。此外,您的表变量是否具有唯一的群集?胡安对LIKE的评论也是如此。这肯定会伤害到某些事情......可能比其他事情更重要。这是基于我所说的粗略版本。

INSERT INTO @varTable
select distinct C.id
from client C
INNER JOIN place pl ON pl.plid = C.id
LEFT OUTER JOIN country ctr ON ctr.nr = pl.country
LEFT OUTER JOIN person per ON per.id = C.id
LEFT OUTER JOIN property pr ON pr.id = C.id
    WHERE 
    (           
            (NOT PR.VALUE IS NULL AND PR.VALUE LIKE '%' + @varSearch  + '%')
            OR (pl.pl_a_name LIKE '%' + @FIRST_WORD + '%')
            OR (NOT pl.add1 IS NULL AND pl.add1 LIKE '%' + @varSearch + '%')
            OR (NOT pl.add2 IS NULL AND pl.add2 LIKE '%' + @varSearch + '%')
            OR (NOT pl.add3 IS NULL AND pl.add3 LIKE '%' + @varSearch + '%')
            OR (NOT pl.pcod IS NULL AND pl.pcod LIKE '%' + @varSearch + '%')
            OR (NOT pl.descr IS NULL AND pl.descr LIKE '%' + @varSearch + '%')
            OR (NOT pl.phone IS NULL AND pl.phone LIKE '%' + @varSearch + '%')
            OR (NOT per.ctname IS NULL AND per.ctname LIKE '%' + @varSearch + '%') 
            OR (NOT per.phone IS NULL AND per.phone LIKE '%' + @varSearch + '%')                                            
    )
    AND
    C.COMPANY = @cia
    and (@DEPT IS NULL OR C.DEPT in (SELECT nstr FROM iter_charlist_to_table(@DEPT_LIMIT,DEFAULT)))
    AND ( (@state = 1 AND STATUS != '0') OR (@state <> 1  and STATUS = 'C') )       

SELECT DISTINCT C.id, listpos
INTO #DistinctClient
from @varTable C
INNER JOIN place pl ON pl.plid = C.id 
LEFT OUTER JOIN country ctr ON ctr.nr = pl.country
LEFT OUTER JOIN person per ON per.id = C.id
LEFT OUTER JOIN property pr ON pr.id = C.id
INNER JOIN iter_charlist_to_table(@SEARCH_NAME, ' ') L ON
    (           
            (NOT PR.VALUE IS NULL AND PR.VALUE LIKE '%' + L.str  + '%')
            OR (pl.pl_a_name LIKE '%' + L.str + '%')
            OR (NOT pl.add1 IS NULL AND pl.add1 LIKE '%' + L.str + '%')
            OR (NOT pl.add2 IS NULL AND pl.add2 LIKE '%' + L.str + '%')
            OR (NOT pl.add3 IS NULL AND pl.add3 LIKE '%' + L.str + '%')
            OR (NOT pl.pcod IS NULL AND pl.pcod LIKE '%' + L.str + '%')
            OR (NOT pl.descr IS NULL AND pl.descr LIKE '%' + L.str + '%')
            OR (NOT pl.phone IS NULL AND pl.phone LIKE '%' + L.str + '%')
            OR (NOT per.ctname IS NULL AND per.ctname LIKE '%' + L.str + '%') 
            OR (NOT per.phone IS NULL AND per.phone LIKE '%' + L.str + '%')                     
            OR (NOT per.cellphone IS NULL AND per.cellphone LIKE '%' + L.str + '%')                     
    )

CREATE UNIQUE CLUSTERED INDEX ix_DistinctClientClustered ON #DistinctClient (id, listpos)

INSERT INTO @tempResults
SELECT TOP 100 OBJ_NO
FROM #DistinctClient
GROUP BY id
HAVING SUM(listpos) = @wsum

END