ORDER BY 實現「刪除最舊/最新 N 筆」DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name
[WHERE where_definition]
[ORDER BY ...]
[LIMIT row_count]
-- 刪除所有行(保留表結構)
DELETE FROM table_name;
-- 或
DELETE * FROM table_name;
-- 僅刪除前 30 筆(無 ORDER BY 時順序不確定)
DELETE FROM db LIMIT 30;
-- 刪除最舊 1 筆(需 ORDER BY)
DELETE FROM somelog WHERE user = 'jcole' ORDER BY timestamp_column LIMIT 1;
-- 實務:分批刪除符合條件的資料,每批 100 筆
DELETE FROM tag_list WHERE aid = '6666' LIMIT 100;
LIMIT N 等同 LIMIT 0, N:刪除前 N 筆LIMIT offset, count(與 SELECT 不同),即無法直接「跳過前 100 筆刪除後 50 筆」ORDER BY 確保確定性順序直接使用會報錯:
DELETE t1 FROM t1 JOIN t2 ON t1.id=t2.id LIMIT 10;
-- ERROR 1064: You have an error in your SQL syntax near 'limit 10'
DELETE A FROM test1 A
INNER JOIN (SELECT id FROM test2 LIMIT 10) B
ON A.id = B.id;
原理:子查詢先以 LIMIT 取得目標主鍵集合,外層按主鍵精確刪除,避開多表 LIMIT 限制。
-- 1. 先查出需刪除的主鍵批次
SELECT id FROM t1
JOIN t2 ON t1.id = t2.id
WHERE t2.status = 'deleted'
ORDER BY t1.id
LIMIT 1000;
-- 2. 應用層迴圈分批執行
DELETE FROM t1 WHERE id IN (批次ID列表);
DELETE FROM t2 WHERE id IN (批次ID列表);
WHERE 條件與 ORDER BY 欄位需有索引,否則全表掃描 + filesort 極慢usleep(100000) (0.1s) 降低主從延遲與鎖衝突ROW_COUNT() 判斷是否結束pt-archiver (Percona Toolkit) 或重建表法DELETE ... LIMIT 是線上安全刪除大量資料的利器。單表直接用,多表用子查詢繞過。核心要訣:有索引、小批次、加間隔、看進度。