我有一個查詢需要2.5秒的FULL JOIN,40秒的INNER,RIGHT或LEFT JOIN。INNER/RIGHT/LEFT JOIN如何比FULL JOIN慢14倍?
這是查詢。子查詢(完成兩次)僅需要1.3秒。
SELECT T1.[time], T1.Total, T1.rn, T2.[time], T2.Total, T2.rn
FROM
(
select [time], MAX(ComputedValue) as Total, row_number() over (order by [time]) as rn
FROM
(
select SUBSTRING(CONVERT(CHAR(10), IntervalStartTime, 108), 0, 6) as [time], ComputedValue
from LoadTestTransactionSample
where LoadTestRunId=285
and CounterName='Total Transactions'
and TransactionName='Export'
) foo
group by [time]
) T1
_____ JOIN
(
select [time], MAX(ComputedValue) as Total, row_number() over (order by [time]) as rn
FROM
(
select SUBSTRING(CONVERT(CHAR(10), IntervalStartTime, 108), 0, 6) as [time], ComputedValue
from LoadTestTransactionSample
where LoadTestRunId=285
and CounterName='Total Transactions'
and TransactionName='Export'
) foo
group by [time]
) T2
ON T1.rn = T2.rn - 1
的select SUBSTRING
位是剛開的HH:MM串出一個DateTime的。 LoadTestTransactionSample
實際上是一個連接8個表的VIEW。 (僅供參考,數據庫是Visual Studio負載測試結果存儲區)。下面是它的(相關)列:
LoadTestRunId INT NOT NULL
CounterName NVARCHAR(255) NOT NULL
TransactionName NVARCHAR(64) NOT NULL
IntervalStartTime DATETIME NOT NULL
IntervalEndTime DATETIME NOT NULL
ComputedValue REAL
一個完整的JOIN返回一個額外的不必要的行,所以我需要做右連接,以得到正確的答案。
我真的不尋找一個解決方案(我有一個:
預取子查詢到表變量
使用SQL Server 2012的解析函數「LAG」,感謝@ a1ex07),只是一些理解爲到什麼可能會導致這些連接類型之間性能的極端差異。
編輯: 這裏的slow right join query plan和fast full join query plan。它們太大而不能發佈屏幕截圖。
編輯2: 實際上查詢計劃具有RIGHT JOIN在45%和FULL JOIN在55%,這證明是完全不準確的(實際上它結束了差於99%/ 1%)。我想這意味着我必須依靠實際的執行統計數據。
編輯3: 統計緩慢RIGHT JOIN:
(40 row(s) affected)
Table 'LoadTestPerformanceCounterCategory'. Scan count 0, logical reads 37556, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'LoadTestPerformanceCounter'. Scan count 0, logical reads 176464, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'LoadTestScenario'. Scan count 0, logical reads 176464, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'LoadTestCase'. Scan count 0, logical reads 176464, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'WebLoadTestTransaction'. Scan count 0, logical reads 13411100, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'LoadTestPerformanceCounterInstance'. Scan count 0, logical reads 36563718, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'LoadTestPerformanceCounterSample'. Scan count 19721, logical reads 269657, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'LoadTestRunInterval'. Scan count 41, logical reads 205, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 36754 ms, elapsed time = 36763 ms.
統計快速FULL JOIN:
(41 row(s) affected)
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'LoadTestPerformanceCounterCategory'. Scan count 0, logical reads 1832, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'LoadTestPerformanceCounter'. Scan count 0, logical reads 8608, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'LoadTestScenario'. Scan count 0, logical reads 8608, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'LoadTestCase'. Scan count 0, logical reads 8608, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'WebLoadTestTransaction'. Scan count 0, logical reads 654200, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'LoadTestPerformanceCounterInstance'. Scan count 0, logical reads 1783596, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'LoadTestPerformanceCounterSample'. Scan count 962, logical reads 13154, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'LoadTestRunInterval'. Scan count 2, logical reads 10, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 1950 ms, elapsed time = 1944 ms.
的右連接正在做大量更多的讀取和掃描速度比多儘管有一個明顯類似的查詢計劃,但仍然是FULL JOIN。
是工作臺(在FULL JOIN中)提示?這是一個臨時表嗎?
這似乎表明查詢優化器已損壞?
設置你的查詢計劃/顯示統計數據,查看。沒有DDL腳本能夠複製你的模式和數據,任何答案基本上都是猜測。此外,這些性能數字在第一個查詢上與後續查詢不同嗎?這表明您的緩存正在捲入。 – Heather 2013-03-07 23:26:23
我認爲希瑟意味着要求你運行它們1-2-3-4,然後4-3-2-1並比較 – 2013-03-07 23:28:29
而且,每個查詢版本都會在緩存中生成自己的查詢計劃,而這些並不一定同時刷新。這可能會導致偶然的性能難題。 – 2013-03-07 23:30:12