[英]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.