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