このようなクエリは、グループごとの上位10個のスコアが「foo」の値になるようにする「グループごとの最大」という意味で言い換えることができます。
質問を実行して段階的に最適化する方法から始めて、この質問を驚くほど詳しく扱うthis linkをご覧ください。あなたは(すなわちGROUP BY foo
をやって想像)foo
のすべてレベルにわたってこれを実行したい場合は
set @num := 0, @foo := '';
select foo, score
from (
select foo, score,
@num := if(@foo = foo, @num + 1, 1) as row_number,
@foo := foo as dummy
from tablebar
where foo IN ('abc','def')
order by foo, score DESC
) as x where x.row_number <= 10;
することは、あなたはwhere foo in ...
ラインを省略することができます。
基本的に内側のクエリ(SELECT foo, score FROM tablebar WHERE foo IN ('abc','def') ORDER BY foo, score DESC
)は降順スコア次いでfoo
ことにより、第1注文と、テーブルからfoo
とscore
グラブ。
@num := ...
は1行ごとに増加し、新しい値がfoo
になるごとに1にリセットされます。つまり、@num
は単なる行番号/ランクです(内側のクエリを独自に実行して、意味を調べてみてください)。
外部クエリは、次に、ランク/行数が10以下である行を選択
注:
は
UNION
を使用して元のクエリは、重複を削除した場合のでfoo='abc'
ためのトップ10スコアがすべて100の場合、(foo,score)
ペアが10回複製されるため、1つの行のみが返されます。これは重複を返します。
多分現在のパフォーマンスに近いところでも解決策があります – zerkms