2013-10-29 24 views
5

Sorumu MySQL optimizasyonu ve iyi uygulama hakkında.MySQL: FIYAT/GRUP BY

Sipariş tercihi ile tercüme edilen metin listesini almam gerekiyor: eğer ingilizce metin bulamıyorsam, Fransızca metin kullanmak istiyorum ve varsa, ispanyolca kullanmak istiyorum.

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 

Ve istediğim: Başka bir deyişle

, ben

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

yüzden this, this, that veya that gibi bazı konular okuyun. Tamam. Bu çalıştı: Ben bu sorguyu İZAH zaman

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

Ama, okuyabiliyorum:

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 

Yani çünkü alt sorgunun, optimize edilmemiş. Bu alt soruyu önleyebilir miyim?

cevap

2

Her dil için JOIN bir tabloyu id numaralı tabloya öneririm. Boş sonuçlara izin vermek için LEFT JOIN kullanabilirsiniz. Sorgu hala tüm tabloyu taramak zorunda olduğu için geçici/filesort kullanacaktır (daha fazla sınırlamak için WHERE kullanabilirsiniz, ancak sadece ilk tablo için). Birleştirilmiş tablolardaki aramalar hızlı olmalıdır.

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

İlginç, COALESCE' 'bilmiyordum! – xiankai