繁体   English   中英

SQL Server 2008 R2存储过程很慢

[英]SQL Server 2008 R2 stored procedure is slow

我要加入3个不同的表以实现自动完成功能,并且必须快速。 建议必须很好,迅速地返回。 我需要通过3个不同的字段来查找LIKE运算符的答案。 请参阅下面的详细信息。

DECLARE @Space AS CHAR(1) = ' ';

 SELECT TOP (@QuantityToReturn) * 
 FROM
     (SELECT
          C.CMPID, C.CMPNAME, C.CMPTHEIRCODE, AD.ADTOWN
      FROM COMPANY C
      JOIN [dbo].[COMPADDRESS] CA ON CA.CMPID = C.CMPID
      JOIN [dbo].[ADDRESS] ad ON AD.ADID = CA.ADID
      JOIN [dbo].SUPPLIER SUP ON C.CMPID = SUP.CMPID
      WHERE 
          (C.CMPID = @LoggedInUserId
           OR @LoggedInUserId = dbo.fnIsAParentCompanyOf(@LoggedInUserId, C.CMPID) 
           OR @LoggedInUserId = 12345)

      UNION 

      SELECT
          C.CMPID, C.CMPNAME, C.CMP_THEIRCODE, AD.ADTOWN
      FROM COMPANY C
      JOIN [dbo].[COMPADDRESS] CA ON ca.CMPID = C.CMPID
      JOIN [dbo].[ADDRESS] AD ON AD.ADID = CA.ADID
      JOIN [dbo].CUSTOMER CUS ON C.CMPID = CUS.CMPID AND CUS.CUSTISTHIS = 1
      WHERE 
          (C.CMPID = @LoggedInUserId
           OR @LoggedInUserId = dbo.fnIsAParentCompanyOf(@LoggedInUserId, C.CMPID) 
           OR @LoggedInUserId = 12345)
      ) AS Results
      WHERE 
          (CMPNAME + @Space + ADTOWN + @Space + CMPTHEIRCODE) LIKE '%' + @Query + '%'

上面的代码很慢(〜9sec)

  • 如果使用: WHERE CMPNAME LIKE '%' + @Query + '%' = quick;
  • 如果我使用: WHERE ADTOWN LIKE '%' + @Query + '%' = quick;
  • 如果我使用: WHERE CMPTHEIRCODE LIKE '%' + @Query + '%' = quick;

只是当我连接它们时,速度变慢了吗?

我会尝试的是这样的:

WHERE 
    LEN(@Query) <> LEN(REPLACE(@Query, CMPNAME, ''))

    AND (LEN(@Query) <> LEN(REPLACE(@Query, ADTOWN, ''))
         AND CHARINDEX(CMPNAME, @Query) = (CHARINDEX(ADTOWN, @Query) - 1 - LEN(CMPNAME)) 
        ) -- making sure that the value of ADTOWN comes after CMPNAME

    AND (LEN(@Query) <> LEN(REPLACE(@Query, CMPTHEIRCODE, ''))
         AND CHARINDEX(ADTOWN, @Query) = (CHARINDEX(CMPTHEIRCODE, @Query) - 1 - LEN(ADTOWN))
        ) -- making sure that the value of CMPTHEIRCODE comes after ADTOWN

我尝试重新实现您的3个条件的逻辑,以便在参数上而不是在具有索引的列上运行。 我的假设是在这种情况下将使用索引。

PS:查找/减去charindex的结果时,需要进行一些细微的调整,以防万一我在计算中犯了一些错误,但是希望您能理解。 -SQLFiddle以验证CHARINDEX()比较是否正确

另外,我建议/尝试对查询的顶部进行一些其他更改,以便最终脚本如下所示:

DECLARE @Space AS CHAR(1) = ' ';

SELECT TOP (@QuantityToReturn) *
FROM (
    SELECT C.CMPID
        ,C.CMPNAME
        ,C.CMPTHEIRCODE
        ,AD.ADTOWN
    FROM COMPANY C
    INNER JOIN [dbo].[COMPADDRESS] CA
        ON CA.CMPID = C.CMPID
    INNER JOIN [dbo].[ADDRESS] ad
        ON AD.ADID = CA.ADID
    WHERE (
            C.CMPID = @LoggedInUserId
            OR @LoggedInUserId = dbo.fnIsAParentCompanyOf(@LoggedInUserId, C.CMPID)
            OR @LoggedInUserId = 12345
            )
        AND EXISTS (
            SELECT 1
            FROM [dbo].SUPPLIER SUP
            WHERE C.CMPID = SUP.CMPID
            )

    UNION

    SELECT C.CMPID
        ,C.CMPNAME
        ,C.CMP_THEIRCODE
        ,AD.ADTOWN
    FROM COMPANY C
    INNER JOIN [dbo].[COMPADDRESS] CA
        ON ca.CMPID = C.CMPID
    INNER JOIN [dbo].[ADDRESS] AD
        ON AD.ADID = CA.ADID
    WHERE (
            C.CMPID = @LoggedInUserId
            OR @LoggedInUserId = dbo.fnIsAParentCompanyOf(@LoggedInUserId, C.CMPID)
            OR @LoggedInUserId = 12345
            )
        AND EXISTS (
            SELECT 1
            FROM [dbo].CUSTOMER CUS
            WHERE C.CMPID = CUS.CMPID
                AND CUS.CUSTISTHIS = 1
            )
    ) AS Results
WHERE LEN(@Query) <> LEN(REPLACE(@Query, CMPNAME, ''))
    AND (
        LEN(@Query) <> LEN(REPLACE(@Query, ADTOWN, ''))
        AND CHARINDEX(CMPNAME, @Query) = (CHARINDEX(ADTOWN, @Query) - 1 - LEN(CMPNAME))
        ) -- making sure that the value of ADTOWN comes after CMPNAME
    AND (
        LEN(@Query) <> LEN(REPLACE(@Query, CMPTHEIRCODE, ''))
        AND CHARINDEX(ADTOWN, @Query) = (CHARINDEX(CMPTHEIRCODE, @Query) - 1 - LEN(ADTOWN))
        ) -- making sure that the value of CMPTHEIRCODE comes after ADTOWN

希望能帮助到你。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM