2013-10-29 22 views
5

Câu hỏi của tôi là về tối ưu hóa MySQL và thực hành tốt.MySQL: ORDER BY FIELD/GROUP BY

Tôi phải nhận danh sách văn bản đã dịch với thứ tự ưu tiên: nếu tôi không thể tìm thấy văn bản bằng tiếng Anh, tôi muốn sử dụng văn bản tiếng Pháp và nếu nó không tồn tại, tôi muốn sử dụng tiếng Tây Ban Nha.

Nói cách khác, tôi có:

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 

Và tôi muốn:

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

Vì vậy, tôi đọc một số chủ đề như this, this, that, hoặc that. Được. Tôi cố gắng này:

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

Nhưng, khi tôi giải thích truy vấn này, tôi có thể đọc:

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 

Vì vậy, nó không được tối ưu hóa, vì subquery. Tôi có thể tránh truy vấn con này không?

Trả lời

2

Tôi sẽ đề xuất JOIN ing trên bàn bằng id cho từng ngôn ngữ. Bạn có thể sử dụng một số LEFT JOIN để cho phép kết quả rỗng. Truy vấn sẽ vẫn sử dụng tạm thời/filesort vì nó phải quét toàn bộ bảng (bạn có thể sử dụng WHERE để hạn chế nó nhiều hơn), nhưng chỉ cho bảng đầu tiên. Tra cứu trên các bảng đã tham gia sẽ nhanh chóng.

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

Thú vị, không biết về 'COALESCE'! – xiankai