sql >> Database >  >> RDS >> Mysql

Optimaliseer MySQL-query om te voorkomen Gebruik waar; Tijdelijk gebruiken; Bestandssorteren gebruiken

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

Als uw tafel MyISAM is of id is geen PRIMARY KEY , moet u een samengestelde ondex maken op (topic_id, id) .

Als uw tabel InnoDB is en id is een PRIMARY KEY , een index alleen op (topic_id) zal doen (id wordt impliciet aan de index toegevoegd).

Bijwerken

Deze zoekopdracht zal hoogstwaarschijnlijk nog efficiënter zijn, op voorwaarde dat u indexen heeft op (topic_id, id) en (date, id) :

Zie dit artikel in mijn blog voor prestatiedetails:

Deze query is voltooid in 30 ms op een 100,000 rijen voorbeeldgegevens:

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

Beide indexen zijn vereist om deze zoekopdracht efficiënt te laten zijn.

Als uw tabel InnoDB is en id is een PRIMARY KEY , dan kunt u id weglaten uit de indexes hierboven.



  1. QSqlDatabase open retourneert altijd waar na update

  2. Terugdraaien naar traditionele replicatie vanuit GTID

  3. Hoe groeipercentage van maand tot maand te berekenen in MySQL

  4. De beste manier om datums in verschillende tijdzones in PHP op te slaan/weer te geven?