FULL JOIN で 2.5 秒、INNER、RIGHT、または LEFT JOIN で 40 秒かかるクエリがあります。
これがクエリです。サブクエリ (2 回実行) は、単独で 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
ビットは、DateTime から HH:MM 文字列を取得するだけです。 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
FULL JOIN は余分な不要な行を返すため、正しい答えを得るには RIGHT JOIN を実行する必要があります。
私は実際に解決策を探しているわけではありません(私は解決策を持っています: SQL Server 2012 分析関数 'LAG' を使用してテーブル変数にサブクエリをプリフェッチします。@a1ex07 に感謝します)、何が極端な違いを引き起こす可能性があるかについての理解これらの結合タイプ間のパフォーマンスの違い。
編集: これは、低速右結合クエリ プラン と高速完全結合クエリ プランです。大きすぎてスクリーンショットを投稿できません。
編集 2: 実際には、クエリ プランの RIGHT JOIN は 45%、FULL JOIN は 55% であり、まったく不正確であることがわかります (実際には 99%/1% よりも悪い結果になります)。これは、実際の実行統計に頼らなければならないことを意味していると思います。
EDIT 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.
RIGHT JOIN は、明らかに同様のクエリ プランにもかかわらず、FULL JOIN よりもはるかに多くの読み取りとスキャンを実行しています。
Worktable ( FULL JOIN) はヒントですか? それは一時テーブルですか?
これは、クエリ オプティマイザーが壊れていることを示唆しているように見えますか?