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
あなたのテーブルがMyISAM
またはid
ある場合はPRIMARY KEY
ではありません、あなたは(topic_id, id)
に複合ondexを作成する必要があります。
あなたのテーブルがInnoDB
とid
がPRIMARY KEY
である場合は、行いますちょうど(topic_id)
上のインデックス(id
が暗黙のうちにインデックスに追加されます)。
更新が
このクエリは、おそらく、より効率的になりますが、あなたが(topic_id, id)
と(date, id)
のインデックスを有することを条件とする:
パフォーマンスの詳細については、私のブログにこの記事を参照してください。
このクエリは100,000
行のサンプルデータに30 ms
で完了します。
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
どちらのインデックスが効率的であると、このクエリのために必要とされます。
あなたのテーブルには、InnoDB
とid
であれば、あなたは上記のindexes
からIDを省略することができ、PRIMARY KEY
です。
フィールドリストの 'date'列が曖昧です..? – Matt
@Matt:アップデートを参照 – Quassnoi
@Quassnoi - 何が起こっているか説明できますか?トピックに返信がない場合、「UNION ALL」は「last_reply」を「date」に置き換えますか? – Matt