sql >> Databáze >  >> RDS >> Mysql

MySQL Query Optimization - vnitřní dotazy

Vždy můžete použít EXPLAIN nebo EXPLAIN EXTENDED abyste viděli, co MySql dělá s dotazem

Můžete také napsat svůj dotaz trochu jiným způsobem, zkusili jste následující?

SELECT        s.*, 
              sm.url AS media_url 
FROM          shows AS s
INNER JOIN    show_medias AS sm ON s.id = SM.show_id
WHERE `s`.`id` IN ( 
                        SELECT DISTINCT st.show_id 
                        FROM show_time_schedules AS sts 
                        LEFT JOIN show_times AS st ON st.id = sts.show_time_id 
                        WHERE sts.schedule_date BETWEEN CAST('2012-01-10' AS date) AND CAST('2012-01-14' AS date) 
                        ) 
AND            `s`.`is_active` = 1 
AND            sm.is_primary = 1
ORDER BY       s.name asc 

Bylo by zajímavé vidět, jaký to má účinek. Očekával bych, že to bude rychlejší, protože v tuto chvíli si myslím, že MySql bude spouštět vnitřní dotaz 1 pro každou show, kterou máte (takže jeden dotaz bude spuštěn mnohokrát. Spojení by mělo být efektivnější.)

Nahraďte INNER JOIN za LEFT JOIN, pokud chcete všechny pořady, které nemají řádek v show_medias.

EDIT:

Brzy se podívám na váš EXPLAIN EXTENDED, také by mě zajímalo, jestli chcete zkusit následující; odebere všechny poddotazy:

SELECT        DISTINCT s.*,  
                       sm.url AS media_url  
FROM                   shows AS s 
INNER JOIN             show_medias AS sm ON s.id = SM.show_id
INNER JOIN             show_times AS st ON (s.id = st.show_id)
RIGHT JOIN             show_time_schedules AS sts ON (st.id = sts.show_time_id)

WHERE                  `s`.`is_active` = 1  
AND                    sm.is_primary = 1 
AND                    sts.schedule_date BETWEEN CAST('2012-01-10' AS date) AND CAST('2012-01-14' AS date)  
ORDER BY               s.name asc 

(Také by bylo dobré vidět EXPLAIN EXTENDED na těchto - můžete to přidat do komentářů k tomuto).

Další EDITACE:

Na vašem EXPLAIN EXTENDED (dobrý začátek, jak číst tyto je zde )

Oba klíčové indikátory jsou USING FILESORT a USING TEMPORARY. Doufejme, že druhý dotaz, který doporučuji, by měl odstranit všechny TEMPORARY tabulky (v poddotazu). Zkuste pak nechat ORDER BY vypnuté, abyste viděli, jestli to má nějaký rozdíl (a to můžeme přidat k dosavadním zjištěním :-)

Také vidím, že dotazu potenciálně chybí mnoho vyhledávání v indexu; všechny vaše sloupce ID jsou hlavními kandidáty na shodu indexu (s obvyklým upozornění na index ). Také bych zkusil přidat tyto indexy a poté znovu spustit EXPLAIN EXTENDED, abych zjistil, jaký je nyní rozdíl (UPRAVTE, jak již víme z vašeho komentáře výše!)



  1. Jak vybrat vše před/po určitém znaku v MySQL – SUBSTRING_INDEX()

  2. Vraťte řádky z INSERT s ON CONFLICT bez nutnosti aktualizace

  3. CHYBA:povolení odepřeno pro sekvenci cities_id_seq pomocí Postgres

  4. MySQL vybere jedno pole z tabulky WHERE podmínka ve více řádcích