Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Optymalizacja zapytań MySQL - wewnętrzne zapytania

Zawsze możesz użyć EXPLAIN lub EXPLAIN EXTENDED aby zobaczyć, co MySql robi z zapytaniem

Możesz również napisać swoje zapytanie w nieco inny sposób, czy próbowałeś następujących?

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 

Ciekawe byłoby zobaczyć, jaki jest tego efekt. Spodziewam się, że będzie to szybsze, ponieważ w tej chwili myślę, że MySql będzie uruchamiać wewnętrzne zapytanie 1 dla każdego programu, który masz (tak, aby jedno zapytanie było uruchamiane wiele razy. Złączenie powinno być bardziej wydajne).

Zamień INNER JOIN na LEFT JOIN, jeśli chcesz, aby wszystkie programy, które nie mają wiersza w show_medias.

EDYCJA:

Niedługo przyjrzę się Twojemu WYJAŚNIJ ROZSZERZONE. Zastanawiam się również, czy chcesz spróbować następujących rzeczy; usuwa wszystkie podzapytania:

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 

(Byłoby również dobrze zobaczyć WYJAŚNIENIE ROZSZERZONE w tym przypadku – możesz dodać je do komentarzy do tego).

Dalsza edycja:

Na swoim EXPLAIN EXTENDED (dobry początek czytania tych jest tutaj )

Kluczowymi wskaźnikami są USING FILESORT i USING TEMPORARY. Mam nadzieję, że drugie zapytanie, które polecam, powinno usunąć wszelkie tabele TEMPORARY (w podzapytaniu). Spróbuj następnie wyłączyć ORDER BY, aby zobaczyć, czy to coś zmieni (i możemy dodać to do dotychczasowych wyników :-)

Widzę również, że zapytanie jest potencjalnie pomijane w wielu wyszukiwaniach indeksów; wszystkie Twoje kolumny id są głównymi kandydatami do dopasowania indeksu (ze zwykłym zastrzeżenia dotyczące indeksu ). Spróbowałbym również dodać te indeksy, a następnie ponownie uruchomić EXPLAIN EXTENDED, aby zobaczyć, jaka jest teraz różnica (EDIT, jak już wiemy z twojego komentarza powyżej!)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. jak zapobiec wstrzyknięciu sql z tego zapytania?

  2. Dlaczego MySQL InnoDB jest o wiele wolniejszy przy skanowaniu pełnych tabel niż MyISAM?

  3. Nie można przejść do wiersza 0 w indeksie wyników MySQL 13

  4. MySQL:Tworzenie bazy danych jak?

  5. Zmaterializowany widok w mysql