いくつかの COUNT 関数と GROUP BY 句を使用して、クエリの結果セットを平坦化しようとしています。基本的に、基本的に 1 つのオブジェクトとして処理されるものに対して、12 行以上を返すクエリがあります。さらに、これを引き起こす列は、結果セットが処理された後にのみ合計されるため、これは集計の理想的な時期のようです。例えば:
SELECT
A.ID, A.NAME, A.DETAILS,
COUNT(DISTINCT CASE WHEN B.TYPE = 'ONE' THEN B.ID2 END) AS B1
COUNT(DISTINCT CASE WHEN B.TYPE = 'TWO' THEN B.ID2 END) AS B2
COUNT(DISTINCT CASE WHEN B.TYPE = 'THREE'
AND B.SUBTYPE = 'ONE-ONE' THEN B.ID END) AS B3
FROM A
LEFT JOIN B ON B.A_ID = A.ID
GROUP BY A.ID, A.NAME, A.DETAILS
アイデアは、さまざまなタイプ/サブタイプのすべての一意の関連付けられた B オブジェクトの数を取得することです。問題は、可能なクエリの性質とデータベースの構造 (これは非常に単純化されています。多数の結合、サブクエリ、およびいくつかのパラメーターがありますが、要点を理解するにはこれで十分です) が原因である可能性があります。 A の各インスタンスで B.ID2 の重複した結果を取得します。これには DISTINCT が必要です。そうしないと、A のその値に対してすべての B.ID2 がカウントされ、誤った結果が得られます。残念ながら、これにより、最初の集計関数以外の各集計関数がテーブルスキャンを実行し、Explain で TEMP テーブルを作成することになり、インデックスを作成しても修正されないようです。クエリ自体に大きなパフォーマンスの問題を引き起こす可能性のある大幅な変更を行わずに、重複を排除できるかどうかはわかりません。これがなければ、必要なすべてのタイプ/サブタイプで B に参加し、選択に B.ID2 を含め、クエリが返されたらそれらをカウントアップする必要があります。これにより、結果セットが大幅に肥大化するので、避けたいと思います。
ここで私が行方不明になっている実行可能な代替手段はありますか、またはおそらく tablescan および TEMP テーブルを排除する可能性のある列にインデックスを付ける方法はありますか? それとも、これに対する良い解決策は本当にありませんか?