我想优化此查询
WITH CTE AS
(
SELECT
KladrItemName _KladrItemName
, WordPositionKladrItem _WordPositionKladrItem
, WordPositionAddressString _WordPositionAddressString
, StartPosition _StartPosition
, EndPosition _EndPosition
, Metric _Metric
, IsConstruction _IsConstruction
, WordsCount _WordsCount
, Indeces _Indeces
, WordPositionAddressString _StartWordIndex
, WordPositionAddressString _EndWordIndex
, 1 _StepNumber
FROM
(
SELECT
dbo.tKladrItems.KladrItemName
, dbo.tFoundWords.WordFromAddressString
, dbo.tFoundWords.WordFromKladr
, dbo.tFoundWords.WordPosition AS WordPositionAddressString
, dbo.tWordKladrItems.wordNumber AS WordPositionKladrItem
, dbo.tFoundWords.StartPosition
, dbo.tFoundWords.EndPosition
, dbo.tFoundWords.Metric
, dbo.tFoundWords.IsConstruction
, dbo.tKladrItems.WordsCount
, dbo.tKladrItems.Indeces
FROM
dbo.tWordsFromKladr JOIN dbo.tWordKladrItems ON dbo.tWordsFromKladr.ID = dbo.tWordKladrItems.wordID
JOIN dbo.tFoundWords ON dbo.tFoundWords.WordFromKladr = dbo.tWordsFromKladr.WordFromKladr
JOIN dbo.tKladrItems ON dbo.tWordKladrItems.kladrItemID = dbo.tKladrItems.id
)T
UNION ALL
SELECT
KladrItemName
, WordPositionKladrItem
, WordPositionAddressString
, CASE WHEN StartPosition _EndPosition THEN EndPosition ELSE _EndPosition END -- MAX
, CAST(Metric + _Metric AS numeric(20, 10))
, IsConstruction + _IsConstruction
, WordsCount
, Indeces
, CASE WHEN _StartWordIndex WordPositionAddressString THEN _EndWordIndex ELSE WordPositionAddressString END
, 1 + _StepNumber
FROM
(
SELECT
dbo.tKladrItems.KladrItemName
, dbo.tFoundWords.WordFromAddressString
, dbo.tFoundWords.WordFromKladr
, dbo.tFoundWords.WordPosition AS WordPositionAddressString
, dbo.tWordKladrItems.wordNumber AS WordPositionKladrItem
, dbo.tFoundWords.StartPosition
, dbo.tFoundWords.EndPosition
, dbo.tFoundWords.Metric
, dbo.tFoundWords.IsConstruction
, dbo.tKladrItems.WordsCount
, dbo.tKladrItems.Indeces
FROM
dbo.tWordsFromKladr JOIN dbo.tWordKladrItems ON dbo.tWordsFromKladr.ID = dbo.tWordKladrItems.wordID
JOIN dbo.tFoundWords ON dbo.tFoundWords.WordFromKladr = dbo.tWordsFromKladr.WordFromKladr
JOIN dbo.tKladrItems ON dbo.tWordKladrItems.kladrItemID = dbo.tKladrItems.id
) AS Tab JOIN CTE ON
Tab.KladrItemName = CTE._KladrItemName
AND Tab.WordPositionKladrItem > CTE._WordPositionKladrItem
AND Tab.WordPositionAddressString > CTE._WordPositionAddressString
)
SELECT DISTINCT
_KladrItemName KladrItemName
, _StartPosition StartPosition
, _EndPosition EndPosition
, _Metric SumMetric
, _IsConstruction SumIsConstruction
, _Indeces Indeces
FROM
CTE
WHERE
_StepNumber = _WordsCount
AND (_IsConstruction = 0 or (_IsConstruction = 1 and _WordsCount > 1))
AND _EndWordIndex - _StartWordIndex + 1 = _WordsCount
option (maxrecursion 0)
这样表
SELECT
dbo.tKladrItems.KladrItemName
, dbo.tFoundWords.WordFromAddressString
, dbo.tFoundWords.WordFromKladr
, dbo.tFoundWords.WordPosition AS WordPositionAddressString
, dbo.tWordKladrItems.wordNumber AS WordPositionKladrItem
, dbo.tFoundWords.StartPosition
, dbo.tFoundWords.EndPosition
, dbo.tFoundWords.Metric
, dbo.tFoundWords.IsConstruction
, dbo.tKladrItems.WordsCount
, dbo.tKladrItems.Indeces
FROM
dbo.tWordsFromKladr JOIN dbo.tWordKladrItems ON dbo.tWordsFromKladr.ID = dbo.tWordKladrItems.wordID
JOIN dbo.tFoundWords ON dbo.tFoundWords.WordFromKladr = dbo.tWordsFromKladr.WordFromKladr
JOIN dbo.tKladrItems ON dbo.tWordKladrItems.kladrItemID = dbo.tKladrItems.id
只构建一次。但是当我将它声明为临时表时,执行时间会增加几倍。有没有办法通过构建此表一次来优化它?有没有办法以其他方式对其进行优化?
感谢您的帮助。
答案 0 :(得分:1)
使用:
WITH base_table AS (
SELECT wki.KladrItemName,
fw.WordFromAddressString,
fw.WordFromKladr,
fw.WordPosition AS WordPositionAddressString,
tfk.wordNumber AS WordPositionKladrItem,
fw.StartPosition,
fw.EndPosition,
fw.Metric,
fw.IsConstruction,
wki.WordsCount,
wki.Indeces
FROM dbo.tWordsFromKladr tfk
JOIN dbo.tWordKladrItems wki ON wki.wordID = tkf.ID
JOIN dbo.tFoundWords fw ON fw.WordFromKladr = tfk.WordFromKladr
JOIN dbo.tKladrItems ki ON ki.id = wki.kladrItemID),
cte AS (
SELECT bt.*
FROM base_table bt
UNION ALL
SELECT KladrItemName,
WordPositionKladrItem,
WordPositionAddressString,
CASE WHEN StartPosition _EndPosition THEN EndPosition ELSE _EndPosition END -- MAX,
CAST(Metric + _Metric AS numeric(20, 10)),
IsConstruction + _IsConstruction,
WordsCount,
Indeces,
CASE WHEN _StartWordIndex WordPositionAddressString THEN _EndWordIndex ELSE WordPositionAddressString END,
1 + _StepNumber
FROM base_table)
...
答案 1 :(得分:0)
您可以在语句中创建两个CTE。试试这个:
WITH Sub As
(SELECT i.KladrItemName,
f.WordFromAddressString, f.WordFromKladr,
f.WordPosition WordPositionAddressString,
wi.wordNumber WordPositionKladrItem,
f.StartPosition, f.EndPosition, f.Metric,
f.IsConstruction, i.WordsCount, i.Indeces
FROM dbo.tWordsFromKladr w
JOIN dbo.tWordKladrItems wi ON wi.ID = i.wordID
JOIN dbo.tFoundWords f ON f.WordFromKladr = w.WordFromKladr
JOIN dbo.tKladrItems i ON wi.kladrItemID = i.id ),
CTE As
(SELECT KladrItemName _KladrItemName,
WordPositionKladrItem _WordPositionKladrItem,
WordPositionAddressString _WordPositionAddressString,
StartPosition _StartPosition ,
EndPosition _EndPosition,
Metric _Metric, IsConstruction _IsConstruction,
WordsCount _WordsCount,
Indeces _Indeces,
WordPositionAddressString _StartWordIndex ,
WordPositionAddressString _EndWordIndex,
1 _StepNumber
FROM Sub T
UNION ALL
SELECT KladrItemName, WordPositionKladrItem, WordPositionAddressString,
CASE WHEN StartPosition < _EndPosition
THEN EndPosition ELSE _EndPosition END, -- Max
CAST(Metric + _Metric AS numeric(20, 10)),
IsConstruction + _IsConstruction,
WordsCount, Indeces,
CASE WHEN _StartWordIndex WordPositionAddressString
THEN _EndWordIndex ELSE WordPositionAddressString END,
1 + _StepNumber
FROM Sub Tab
JOIN CTE
ON Tab.KladrItemName = CTE._KladrItemName
AND Tab.WordPositionKladrItem > CTE._WordPositionKladrItem
AND Tab.WordPositionAddressString > CTE._WordPositionAddressString)
SELECT DISTINCT _KladrItemName KladrItemName,
_StartPosition StartPosition, _EndPosition EndPosition,
_Metric SumMetric,_IsConstruction SumIsConstruction,
_Indeces Indeces
FROM CTE
WHERE_StepNumber = _WordsCount
AND (_IsConstruction = 0 or (_IsConstruction = 1 and _WordsCount > 1))
AND _EndWordIndex - _StartWordIndex + 1 = _WordsCountoption
(maxrecursion 0)