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
Nếu bảng của bạn là MyISAM
hoặc id
không phải là PRIMARY KEY
, bạn cần tạo ondex tổng hợp trên (topic_id, id)
.
Nếu bảng của bạn là InnoDB
và id
là một PRIMARY KEY
, một chỉ mục chỉ trên (topic_id)
sẽ làm (id
sẽ được thêm ngầm vào chỉ mục).
Cập nhật
Truy vấn này có lẽ sẽ thậm chí còn hiệu quả hơn, miễn là bạn có các chỉ mục trên (topic_id, id)
và (date, id)
:
Xem bài viết này trong blog của tôi để biết chi tiết về hiệu suất:
Truy vấn này hoàn thành sau 30 ms
trên 100,000
dữ liệu mẫu hàng:
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
Cả hai chỉ mục đều được yêu cầu để truy vấn này hoạt động hiệu quả.
Nếu bảng của bạn là InnoDB
và id
là một PRIMARY KEY
, sau đó bạn có thể bỏ qua id khỏi indexes
ở trên.