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

Zoptymalizuj zapytanie MySQL, aby uniknąć używania where; Korzystanie tymczasowe; Korzystanie z sortowania plików

SELECT  id, name, last_reply, replies
FROM    (
        SELECT  topic_id, MAX(date) AS last_reply, COUNT(*) AS replies
        FROM    wp_pod_tbl_forum
        GROUP BY
                topic_id
        ) r
JOIN    wp_pod_tbl_forum t
ON      t.topic_id = 0
        AND t.id = r.topic_id
UNION ALL
SELECT  id, name, date, 0
FROM    wp_pod_tbl_forum t
WHERE   NOT EXISTS
        (
        SELECT  NULL
        FROM    wp_pod_tbl_forum r
        WHERE   r.topic_id = t.id
        )
        AND t.topic_id = 0
ORDER BY
       date DESC
LIMIT 0, 20

Jeśli Twoja tabela to MyISAM lub id nie jest PRIMARY KEY , musisz utworzyć złożony ondex na (topic_id, id) .

Jeśli Twoja tabela to InnoDB i id to PRIMARY KEY , indeks tylko w (topic_id) zrobi (id zostanie dodana do indeksu).

Aktualizacja

Zapytanie to najprawdopodobniej będzie jeszcze wydajniejsze, pod warunkiem, że masz indeksy na (topic_id, id) i (date, id) :

Zobacz ten artykuł na moim blogu, aby uzyskać szczegółowe informacje na temat wydajności:

To zapytanie kończy się za 30 ms na 100,000 wiersze przykładowe dane:

SELECT  id, name, last_reply,
        (
        SELECT  COUNT(*)
        FROM    wp_pod_tbl_forum fc
        WHERE   fc.topic_id = fl.topic_id
        ) AS replies
FROM    (
        SELECT  topic_id, date AS last_reply
        FROM    wp_pod_tbl_forum fo
        WHERE   id = (
                SELECT  id
                FROM    wp_pod_tbl_forum fp
                WHERE   fp.topic_id = fo.topic_id
                ORDER BY
                        fp.date DESC, fp.id DESC
                LIMIT 1
                )
                AND fo.topic_id <> 0
        ORDER BY
                fo.date DESC, fo.id DESC
        LIMIT 20
        ) fl
JOIN    wp_pod_tbl_forum ft
ON      ft.id = fl.topic_id
UNION ALL
SELECT  id, name, date, 0
FROM    wp_pod_tbl_forum t
WHERE   NOT EXISTS
        (
        SELECT  NULL
        FROM    wp_pod_tbl_forum r
        WHERE   r.topic_id = t.id
        )
        AND t.topic_id = 0
ORDER BY
       last_reply DESC, id DESC
LIMIT  20

Aby to zapytanie było wydajne, wymagane są oba indeksy.

Jeśli Twoja tabela to InnoDB i id to PRIMARY KEY , możesz pominąć id z indexes 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. Zapytanie Django ORM GROUP BY wiele kolumn połączonych przez MAX

  2. Ustawienie poprawnego rozmiaru pliku innodb_log_file_size w mysql

  3. Jak zaktualizować samodzielnie hostowane wordpress i zainstalowane wtyczki witryny na żywo do najnowszych dostępnych wersji bez żadnych problemów?

  4. MySQL - Jak zliczyć wszystkie wiersze na tabelę w jednym zapytaniu

  5. Synchronizacja bazy danych klienta SQLite z bazą danych serwera MySQL