5

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) はヒントですか? それは一時テーブルですか?

これは、クエリ オプティマイザーが壊れていることを示唆しているように見えますか?

4

2 に答える 2

2

OK、答えは次のとおりです。悪いデータベース統計です。ひどい。のように、更新されたことはありません。

exec sp_updatestats;ところで。

【恥ずかしそうに頭を隠す】

于 2013-03-12T21:52:22.367 に答える
1

これは、同様のクエリの実行計画です。テーブルは非常に小さいです。

実行計画

クエリ 1 :

  • を使用しINNER JOINます。
  • 実行計画は小さく見えます。
  • ただし、全体の 62% の時間がかかります。

クエリ 2 :

  • を使用しFULL JOINます。
  • 実行計画は大きく見えます。
  • ただし、全体の 38% の時間がかかります。

理由:私の場合、INNER JOINはHASH MATCHを使用しています。FULL JOIN は NESTED LOOP を使用しています。これは、SQL オプティマイザーによって、どの物理結合を使用する必要があるかが決定されます (ただし、他の物理結合を使用することはできます)。実行計画を確認してください。役に立ちます。

于 2013-03-08T08:06:04.913 に答える