簡體   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