2013-10-29 25 views
5

私の質問はMySQLの最適化と良い方法です。MySQL:ORDER BY FIELD/GROUP BY

私は英語のテキストを見つけることができない場合、私はフランス語のテキストを使用したい、それが存在しない場合、私はスペイン語を使用したいと思います。

id lang text 
1 fr text_FR 
1 en text_EN 
1 es text_ES 
2 fr text_FR2 
3 fr text_FR3 
3 es text_ES3 

を私がしたい:つまり

、私が持っている

id lang text 
1 en text_EN 
2 fr text_FR2 
3 fr text_FR3 

だから私はthisthisthat、またはthatのようないくつかのトピックをお読みください。 OK。 私はこの試みた:

SELECT text FROM (
    SELECT id, text 
    FROM translation 
    ORDER BY FIELD(lang, 'en', 'fr', 'es') 
) tt GROUP BY tt.id; 

をしかし、私はこのクエリをEXPLAINするとき、私は読むことができます:

id select_type table partitions type possible_keys key key_len ref rows Extra 
1 PRIMARY <derived2> NULL ALL NULL NULL NULL NULL 4 Using temporary; Using filesort 
2 DERIVED translation NULL ALL PRIMARY PRIMARY 52  1641  Using filesort 

をだから、それがために、サブクエリの、最適化されていません。このサブクエリを避けることはできますか?

答えて

2

JOINは、各言語でidでテーブルに表示することをお勧めします。 LEFT JOINを使用して、結果を無効にすることができます。クエリは、テーブル全体をスキャンする必要があります(WHEREを使用してさらに制限することができます)ので、最初のテーブルに対してのみ、temporary/filesortを使用します。結合されたテーブルのルックアップはすばやく行う必要があります。

SELECT 
    COALESCE(en.text, fr.text, es.text, any.text) 
FROM 
    f any 
    LEFT JOIN f en ON (any.id = en.id AND en.lang = 'en') 
    LEFT JOIN f fr ON (any.id = fr.id AND fr.lang = 'fr') 
    LEFT JOIN f es ON (any.id = es.id AND es.lang = 'es') 
GROUP BY any.id; 

http://sqlfiddle.com/#!2/baafc/1

+0

興味深い、COALESCE' '知りませんでした! – xiankai