【发布时间】:2021-04-03 09:45:08
【问题描述】:
我有一个从表中选择数据的查询。
此表记录数量因用户输入而异。
当记录数大约为 60,000 或更少时,速度非常快(不到 2 分钟)。
但是当我将大约 120,000 条记录数翻倍时,需要一个多小时!然后我必须终止该进程。
我不知道为什么它非常慢。
我添加了很多索引,但还是太慢了。
这里是查询
DECLARE @MaxID AS bigint
SELECT @MaxId = MAX(iID) from TagsTemp
SELECT
RepID, tag, xmiid, ibegin, iend,
confidence, polarity, uncertainty, conditional, generic, historyOf,
codingScheme, code, cui, /*U.tui,*/ preferredText , --ISNULL(tag2, tag3) AS tagValue,
ISNULL(ibegin2, ibegin3) AS ibeginValue, ISNULL(iend2, iend3) AS iendValue,
dbo.RepGetValue(RepID, ibegin, iend,
ISNULL(ibegin2, ibegin3), ISNULL(iend2, iend3))
FROM
(SELECT DISTINCT
T.RepID, dbo.ShortTag(T.tag) AS tag, T.xmiid,
CAST(T.ibegin AS bigint) AS ibegin, CAST(T.iend AS bigint) AS iend,
T.confidence, T.polarity, T.uncertainty, T.conditional, T.generic, T.historyOf,
dbo.ShortTag(U.codingScheme) AS codingScheme, U.code, U.cui, /*U.tui, */U.preferredText,
dbo.ShortTag(L3.tag) AS tag2, L3.ibegin AS ibegin2, L3.iend AS iend2,
dbo.ShortTag(M1.tag) AS tag3, M1.ibegin AS ibegin3, M1.iend AS iend3,
ROW_NUMBER() OVER(PARTITION BY T.RepID, T.tag, T.xmiid,
CAST(T.ibegin AS bigint), CAST(T.iend AS bigint),
T.confidence, T.polarity, T.uncertainty, T.conditional, T.generic, T.historyOf,
U.codingScheme, U.code, U.cui, /*U.tui,*/ U.preferredText , L3.tag, L3.ibegin, L3.iend
ORDER BY
T.RepID, T.xmiid, CAST(T.ibegin AS bigint), CAST(T.iend AS bigint),
CAST(M1.ibegin AS bigint), CAST(M1.iend AS bigint) DESC,
CASE M1.tag
WHEN 'textsem:Mandy' THEN 1
WHEN 'textsem:Franc' THEN 2
WHEN 'textsem:Roger' THEN 3
WHEN 'syntax:Numan' THEN 4
WHEN 'textsem:Danna' THEN 5
WHEN 'textsem:Rami' THEN 6
END) AS RowNo
FROM
TagsTemp T
INNER JOIN
TagsTemp U ON T.RepID = U.RepID
AND T.Tag IN ('textsem:Michael', 'textsem:Simon', 'textsem:Anna','textsem:Evan','textsem:Paul','textsem:Dines','textsem:Larry')
AND U.Tag = 'refsem:Usman'
AND T.ontologyConceptArr LIKE '%' + CAST(U.xmiid AS varchar(100)) + '%'
LEFT OUTER JOIN
TagsTemp L1 ON T.tag = 'textsem:Larry'
AND L1.tag = 'relation:ResultOfTextRelation'
AND T.RepID = L1.RepID
AND T.LabValue = L1.xmiid
AND ISNULL(L1.arg2, '') <> ''
LEFT OUTER JOIN
TagsTemp L2 ON L1.tag = 'relation:ResultOfTextRelation'
AND L2.tag = 'relation:RelationArgument'
AND L1.RepID = L2.RepID
AND L1.arg2 = L2.xmiid
LEFT OUTER JOIN
TagsTemp L3 ON L2.tag = 'relation:RelationArgument'
AND L3.tag IN ('syntax:Numan','textsem:Danna','textsem:Roger','textsem:Mandy', 'textsem:Franc','textsem:Rami')
AND L2.RepID = L3.RepID
AND L2.argument = L3.xmiid
LEFT OUTER JOIN
TagsTemp M1 ON T.RepID = M1.RepID
AND T.tag IN ('textsem:Michael', 'textsem:Larry')
AND M1.tag IN ('syntax:Numan','textsem:Danna','textsem:Roger', 'textsem:Mandy',/*'textsem:Rami', */ 'textsem:Franc')
AND CAST(M1.ibegin AS bigint) > CAST(T.iend AS bigint)
AND CAST(M1.ibegin AS bigint) - CAST(T.iend AS bigint) < 4
WHERE
T.iID <= @MaxID) X
WHERE
RowNo = 1
ORDER BY
RepID, tag, xmiid, CAST(ibegin AS bigint) , CAST(iend AS bigint) ,
confidence, polarity, uncertainty, conditional, generic, historyOf,
codingScheme, code, cui, /*U.tui,*/ preferredText , tag2, ibegin2, iend2,
tag3,ibegin3, iend3
这是我跑 60,000 时的执行计划
【问题讨论】:
-
看到不同的选择通常表示查询设计不正确。并且看到一个行号被划分为许多字段,这些字段有时甚至被强制转换,并按大量列排序......也许您应该回顾一下您的要求,看看它们是否超出了顶部。
-
好吧,我建议先单独测试大子查询。
-
您的查询非常复杂,几乎无法维护。我会把它放在一个存储过程中,并将所有这些分解成可管理的部分。想想那个会破译这个的可怜人。
-
好吧,目标可能很崇高,但恕我直言,方法过于复杂。您需要将所有这些分解为可管理的部分,即使从性能的角度来看,您也可以单独进行测试。查看我的其他建议。
-
祝你好运!此外,请仔细记录每个步骤,以免在 6 个月后回到此代码时迷失方向。放大量的 cmets 解释你为什么这样做。
标签: sql-server performance sql-execution-plan