クエリは次のように記述します:
SELECT c.time
, SUM(c.counter)
, MAX(p.clustername) AS clustername
FROM cell c
JOIN swap_plan p
ON p.siteid = c.siteid
AND p.clustername = 'Cluster A'
WHERE c.time >= 'day1'
AND c.time <= 'day2'
GROUP
BY c.time
cell
には必ずインデックスがあります time
先頭の列として。
MySQLは、同じインデックスを使用して(WHERE句の)範囲述語を満たし、「Usingfilesort」操作なしでGROUPBYを満たすことができます。
... ON cell (time)
列のサイズによっては、カバーインデックスが最適なパフォーマンスを提供する場合があります。カバーするインデックスには、クエリで参照されるテーブルのすべての列が含まれるため、基になるテーブルのページを検索しなくても、インデックスページからクエリを完全に満たすことができます。
... ON cell (time, siteid, counter)
swap_plan
のインデックスの場合 、site_id
のインデックスがあります 先頭の列として、clustername
を含みます 列、次のいずれか:
... ON swap_plan (clustername, site_id)
または
... ON swap_plan (site_id, clustername)
これらの2つの列の組み合わせ、つまりsite_id
の値には、UNIQUE制約が存在する可能性があります。 特定のclustername
に対して区別されます 。 (そうでない場合は、同じ(site_id,clustername)
タプルが複数回出現するため、合計でcounter
になる可能性があります。 膨らませる。
EXPLAIN
を探しています swap_plan
への「ref」ルックアップを表示する出力 c.siteid
の値からのテーブル クラスター名のconst(リテラル'クラスターA')値。
31行と368行のサイズのテーブルでは、最適な実行プランと恐ろしい実行プランの間でパフォーマンス(経過時間)に大きな違いは見られません。
いずれかのテーブルが数百万行にスケールアップすると、違いが明らかになります。オプティマイザによる実行プランの選択は、各テーブルの統計(サイズ、行数、列のカーディナリティ)の影響を受けるため、テーブルサイズの増加に伴って実行プランが変わる可能性があります。