SELECT id, name FROM `table`
WHERE name IN (
SELECT name FROM `table`
GROUP BY name HAVING COUNT(*) > 1
);
MySQL 5.6 前子查詢優化差,易全表掃描外層表。
-- 1. 建臨時表存重複 name
CREATE TEMPORARY TABLE tmp_dup AS
SELECT name FROM `table` GROUP BY name HAVING COUNT(*) > 1;
-- 2. JOIN 查詢
SELECT a.id, a.name FROM `table` a
JOIN tmp_dup t ON a.name = t.name;
實測:百萬行從 10 秒降至 0.3 秒。
WITH dup AS (
SELECT name FROM `table` GROUP BY name HAVING COUNT(*) > 1
)
SELECT a.id, a.name FROM `table` a JOIN dup ON a.name = dup.name;
CTE 會自動物化,效能同臨時表,語法更乾淨。
SELECT DISTINCT a.id, a.name FROM `table` a JOIN tmp_dup t ON a.name = t.name;