[英]Why is this SQL Server query so slow?
該查詢需要4秒鍾才能運行,它返回大約62000行。 @ c,@ p和@a是由整數組成的字符串,根據需要過濾的內容,以逗號分隔或為空。不幸的是,這不能更改。
我試圖在不使用過濾器的情況下運行此程序,但這沒有任何區別。 我對SQL相當陌生。
這里有3個常用的表表達式,可以減少多余的代碼行。
我希望能夠在不到一秒鍾的時間內運行
DECLARE @UId int = '817',
@c varchar(max) = '',
@p varchar(max) = '',
@a varchar(max) = ''
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
IF OBJECT_ID('tempdb..#FilteredData') IS NOT NULL
DROP TABLE #FilteredData;
WITH cteuag AS
(
SELECT
uag.CId,
uag.AuthorIsatIonGroupId,
rn = ROW_NUMBER() OVER (PARTITION BY uag.[UId], uag.CId, uag.AuthorIsatIonGroupId ORDER BY uag.CId)
FROM
uag
WHERE
uag.[UId] = @UId
AND uag.IsDeleted = 0
AND (@c = '' OR (@c LIKE CONVERT(varchar(4), uag.CId)
OR @c LIKE '%,' + CONVERT(varchar(4), uag.CId) + ',%'
OR @c LIKE CONVERT(varchar(4), uag.CId) + ',%'
OR @c LIKE '%,' + CONVERT(varchar(4), uag.CId))
)
),
cteuc AS
(
SELECT
uc.CId,
cteuag.AuthorIsatIonGroupId,
uc.[UId],
i.FirstName + Iif(i.MiddleName IS NOT NULL, ' ' + i.MiddleName + ' ', ' ') + i.Surname AS [AName],
rn = ROW_NUMBER() OVER (PARTITION BY uc.CId, uc.[UId] ORDER BY uc.ModifiedAt)
FROM
uc
INNER JOIN
cteuag ON cteuag.CId = uc.CId
AND uc.IsDeleted = 0
AND (@a = '' OR (@a LIKE CONVERT(varchar(4), uc.[UId])
OR @a LIKE '%,' + CONVERT(varchar(4), uc.[UId]) + ',%'
OR @a LIKE CONVERT(varchar(4), uc.[UId]) + ',%'
OR @a LIKE '%,' + CONVERT(varchar(4), uc.[UId]))
)
INNER JOIN
ui ON ui.[UId] = uc.[UId]
AND ui.IsDeleted = 0
INNER JOIN
i ON i.PId = ui.IndividualId
),
ctel AS
(
SELECT
la.LId,
p.CId,
la.[UId],
rn = ROW_NUMBER() OVER (PARTITION BY la.LId ORDER BY la.DateUpdated DESC)
FROM
la
INNER JOIN
p ON p.Id = la.PId
AND p.IsDeleted = 0
AND la.IsDeleted = 0
AND la.[UId] IS NOT NULL
INNER JOIN
l ON la.LId = l.Id
AND l.IsDeleted = 0
)
SELECT
c.Id AS CId,
c.[Name] AS CName,
u.Id AS AId,
cteuc.AName AS AName,
ctel.LId AS LId,
qh.Id AS QhId,
q.Id AS QId,
q.IsTrue AS isTrue,
p.Id AS PId,
p.[Name] AS PName,
qi.FinalCalculation AS Calculation
INTO
#FilteredData
FROM
c
INNER JOIN
cteuc ON cteuc.CId = c.Id
AND cteuc.Rn = 1
AND c.IsDeleted = 0
LEFT OUTER JOIN
u ON u.Id = Iif(cteuc.AuthorIsatIonGroupId = 1, @UId, cteuc.[UId])
AND u.IsDeleted = 0
LEFT OUTER JOIN
ctel ON ctel.CId = c.Id
AND ctel.Rn = 1
AND ctel.[UId] = u.Id
LEFT OUTER JOIN
(la
INNER JOIN
qla ON qla.LeadActivityId = la.Id
AND la.IsDeleted = 0
AND la.ActivityTypeId = 4
INNER JOIN
qh ON qla.QhId = qh.Id
AND qh.IsDeleted = 0
AND qh.IsReRated = 0
LEFT OUTER JOIN
(q
INNER JOIN
p ON p.Id = q.PId
AND q.IsDeleted = 0
AND p.IsDeleted = 0
) ON q.QhId = qh.Id) ON la.[UId] = u.Id
AND la.LId = ctel.LId
AND
(
@p = ''
OR
(
@p LIKE CONVERT(varchar(4), p.Id)
OR @p LIKE '%,' + CONVERT(varchar(4), p.Id) + ',%'
OR @p LIKE CONVERT(varchar(4), p.Id) + ',%'
OR @p LIKE '%,' + CONVERT(varchar(4), p.Id)
)
)
LEFT OUTER JOIN
(
SELECT
qi1.QId,
SUM(Iif(qi1.Calculation = 0, 0, qi1.Calculation + qi1.Extra)) AS FinalCalculation
FROM qi
WHERE qi1.IsDeleted = 0
GROUP BY QId
) AS qi ON qi.QId = q.Id
WHERE
(
@p = ''
OR
(
p.Id IS NOT NULL
OR qh.Id IS NULL
)
)
SELECT * FROM #FilteredData
編輯 :
只需清楚一點,以上查詢的運行速度不會比此查詢慢:
DECLARE @UId int = '817'
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
IF OBJECT_ID('tempdb..#FilteredData') IS NOT NULL DROP TABLE #FilteredData;
WITH cteuag AS
(
SELECT
uag.CId,
uag.AuthorIsatIonGroupId,
rn = ROW_NUMBER() OVER (PARTITION BY uag.[UId], uag.CId, uag.AuthorIsatIonGroupId ORDER BY uag.CId)
FROM uag
WHERE uag.[UId] = @UId
AND uag.IsDeleted = 0
),
cteuc AS
(
SELECT
uc.CId,
cteuag.AuthorIsatIonGroupId,
uc.[UId],
i.FirstName + Iif(i.MiddleName IS NOT NULL, ' ' + i.MiddleName + ' ', ' ') + i.Surname AS [AName],
rn = ROW_NUMBER() OVER (PARTITION BY uc.CId, uc.[UId] ORDER BY uc.ModifiedAt)
FROM uc
INNER JOIN cteuag ON cteuag.CId = uc.CId
AND uc.IsDeleted = 0
INNER JOIN ui ON ui.[UId] = uc.[UId]
AND ui.IsDeleted = 0
INNER JOIN i ON i.PId = ui.IndividualId
),
ctel AS
(
SELECT
la.LId,
p.CId,
la.[UId],
rn = ROW_NUMBER() OVER (PARTITION BY la.LId ORDER BY la.DateUpdated DESC)
FROM la
INNER JOIN p ON p.Id = la.PId
AND p.IsDeleted = 0
AND la.IsDeleted = 0
AND la.[UId] IS NOT NULL
INNER JOIN l ON la.LId = l.Id
AND l.IsDeleted = 0
)
SELECT
c.Id AS CId,
c.[Name] AS CName,
u.Id AS AId,
cteuc.AName AS AName,
ctel.LId AS LId,
qh.Id AS QhId,
q.Id AS QId,
q.IsTrue AS isTrue,
p.Id AS PId,
p.[Name] AS PName,
qi.FinalCalculation AS Calculation
INTO #FilteredData
FROM c
INNER JOIN cteuc ON cteuc.CId = c.Id
AND cteuc.Rn = 1
AND c.IsDeleted = 0
LEFT OUTER JOIN u ON u.Id = Iif(cteuc.AuthorIsatIonGroupId = 1, @UId, cteuc.[UId])
AND u.IsDeleted = 0
LEFT OUTER JOIN ctel ON ctel.CId = c.Id
AND ctel.Rn = 1
AND ctel.[UId] = u.Id
LEFT OUTER JOIN
(
la
INNER JOIN qla ON qla.LeadActivityId = la.Id
AND la.IsDeleted = 0
AND la.ActivityTypeId = 4
INNER JOIN qh ON qla.QhId = qh.Id
AND qh.IsDeleted = 0
AND qh.IsReRated = 0
LEFT OUTER JOIN
(
q
INNER JOIN p ON p.Id = q.PId
AND q.IsDeleted = 0
AND p.IsDeleted = 0
) ON q.QhId = qh.Id) ON la.[UId] = u.Id
AND la.LId = ctel.LId
LEFT OUTER JOIN
(
SELECT
qi1.QId,
SUM(Iif(qi1.Calculation = 0, 0, qi1.Calculation + qi1.Extra)) AS FinalCalculation
FROM qi
WHERE qi1.IsDeleted = 0
GROUP BY QId
) AS qi ON qi.QId = q.Id
SELECT * FROM #FilteredData
因此我知道這不是用作過濾器的逗號分隔值,也不是前導通配符。
因此,事實證明它可以在另一台筆記本電腦上正常運行,這意味着這與我的筆記本電腦有關。 無論如何,查看注釋,此查詢可能需要大量改進
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.