0

私は、このように見えるコードのパフォーマンスが遅いセクションに出くわしました。

SELECT
  res.[X],
  res.[Y],
  SUM(res.[Z]) -- This is SUM so I have to remove duplicates
FROM (
  SELECT DISTINCT a.[X], a.[Y], b.[Z] FROM [A] a JOIN [B] b ON a.[ID] = b.[ID]
  UNION
  SELECT DISTINCT a.[X], a.[Y], c.[Z] FROM [A] a JOIN [C] c ON a.[ID] = c.[ID]
  UNION
  SELECT DISTINCT a.[X], a.[Y], d.[Z] FROM [A] a JOIN [D] d ON a.[ID] = d.[ID]
  UNION ALL -- This set won't have duplicates, hence the UNION ALL in this case
  SELECT a.[X], a.[Y], n.[Z] FROM [A] a JOIN [N] n ON a.[ID] = n.[ID]
) res
GROUP BY res.[X], res.[Y]

結合はもっと複雑で、これらの UNION/UNION ALL は 12 個ありますが、全体像がわかります。通常、各結果セットには 1 ~ 1,500 万行が含まれます。

他の誰かがこのクエリをどのように書くのか疑問に思っています。私は警告する他のいくつかのスレッドを読みました:

SELECT DISTINCT * FROM [A]
UNION
SELECT DISTINCT * FROM [B]

DISTINCT が 3 回呼び出されるためです (この小さな例では)。だから私はそれを試して、DISTINCTを削除しました。結果は実際にはかなり遅くなりました。余分なフィルタリングを削除すると、クエリの実行が遅くなる理由がわかりません。

誰にもアイデアはありますか?クエリプランを掘り下げていますが、投稿するには大きすぎるため、提案を探しています。ありがとう!

4

1 に答える 1

0

行番号を使用して、X、Y、および Z ごとに最小値を選択することができます

select 
    MIN(myfilter),
    X,
    Y,
    Z
SELECT 
    a.[X], 
    a.[Y], 
    b.[Z] 
RowNumber() over (order by A.X, a.Y, b.Z) as MyFilter

    FROM [A] a JOIN [B] b ON a.[ID] = b.[ID]
)
group by x,y,z
于 2013-11-01T10:55:48.657 に答える