2016-04-12 17 views
0

döndüren SELECT alt sorgusuyla en iyi duruma getirme Uygulamamdaki bir sayfanın, belirli bir SQL sorgusu nedeniyle çok yavaş yüklendiğini fark ettim.SELECT IN() SQL satırını birçok satır

this document about subquery optimization'u okudum ancak MySQL'in alt sorguları nasıl en iyi duruma getirdiğini değil, sorgularımı nasıl optimize edebileceğimi ana hatlarıyla belirledim. Belgeden aldığım bazı fikirleri denemedim, boşuna.

Bu benim şu andaki yavaş sorgam. Ben okunabilmesi için tablo ve sütun isimleri basitleştirilmiş:

SELECT 
    a.one, a.two, a.three, a.four, 
    b.*, 
    a.id, 
    b.id, 
    c.one, c.id, 
    d.one, 
    f.one 
FROM a 
JOIN b ON a.id = b.a_id 
JOIN c ON c.id = b.c_id 
JOIN e ON b.e_id = e.id 
JOIN d ON d.id = e.d_id 
JOIN f ON f.id = b.f_id 
WHERE a.id IN (
    SELECT a_id FROM b WHERE a_id IS NOT NULL AND g_id = 95 
) 

SEÇ alt sorgu şu anda ben ana sorgu için gecikmeye neden düşünüyorum 750 + satır döndürür. Bütün sorgu 25 saniye sürüyor.

Bu sorguyu nasıl optimize edebilirim?

+0

Hangi tablo g_id'dir? –

cevap

0

5.6.5'ten önce, MySQL alt sorguyu yansıtmaz. Bu katılmak üzerindeki her kayıt için, aşağıdaki bağıntılı sorgu çalıştırmak anlamına gelir:

SELECT 1 
FROM b 
WHERE a_id IS NOT NULL 
     AND g_id = 95 
     /* optimizer added */ 
     AND a_id = a.id 
LIMIT 1 

, iyileştirici tarafından eklenen ek bir koşulu ile.

MySQL, 5.6.5'ten itibaren IN alt sorgusunun sonuçlarını geçici bir tablo halinde gerçekleştirebilir ve başka herhangi bir şekilde birleştirebilir.

kala 5.6.5 MySQL kullanıyorsanız, bir katılmak olarak durumunuzu yeniden deneyebilirsiniz:

SELECT a.one, a.two, a.three, a.four, 
     b.*, 
     a.id, 
     b.id, 
     c.one, c.id, 
     d.one, 
     f.one 
FROM (
     SELECT DISTINCT a_id 
     FROM b 
     WHERE a_id IS NOT NULL 
       AND g_id = 95 
     ) bi 
JOIN a ON a.id = bi.a_id 
JOIN b ON a.id = b.a_id 
JOIN c ON c.id = b.c_id 
JOIN e ON b.e_id = e.id 
JOIN d ON d.id = e.d_id 
JOIN f ON f.id = b.f_id 

ve ilgili tüm alanları düzgün ders endeksinin.

+0

Sonunda şunu ekleyerek çalışmanızı öneriyorum: 'WHERE b.g_id = 95', yani dış sorguyu da filtrelemem gerekiyordu – Obay

+0

Merak ediyorum, bir WHERE EXISTS()' MySQL üzerinde iyi çalışır çok? – deroby

+0

@deroby: evet olurdu – Quassnoi