這裏的問題與我遇到的另一個問題有關...如何找到MySQL記錄集中的ID差距?
我有數以百萬計的記錄,並且每個記錄的ID都是自動遞增的,不幸的是有時候生成的ID有時會被丟棄ID之間有很多差距。
我想找到差距,並重新使用被放棄的ID。
什麼是在MySQL中這樣做的有效方法?
這裏的問題與我遇到的另一個問題有關...如何找到MySQL記錄集中的ID差距?
我有數以百萬計的記錄,並且每個記錄的ID都是自動遞增的,不幸的是有時候生成的ID有時會被丟棄ID之間有很多差距。
我想找到差距,並重新使用被放棄的ID。
什麼是在MySQL中這樣做的有效方法?
首先,您試圖通過重複使用跳過的值來獲得什麼優勢?一個普通的INT UNSIGNED
會讓你數到4,294,967,295。有了「數百萬條記錄」,在用完有效的ID之前,您的數據庫將不得不增長1000倍以上。 (然後使用一個BIGINT UNSIGNED
會使你高達18,446,744,073,709,551,615個值。)
嘗試回收值MySQL跳過了很多時間,可能會耗盡大量的時間來嘗試補償某些實際上不會影響MySQL的內容第一名。
雖這麼說,你可以找到失蹤的ID喜歡的東西:
SELECT id + 1
FROM the_table
WHERE NOT EXISTS (SELECT 1 FROM the_table t2 WHERE t2.id = the_table.id + 1);
這會發現只有第一失蹤每個序列(例如,如果你有{1, 2, 3, 8, 10}
它會找到{4,9}
)的數量,但它很可能是有效的,當然,一旦你填寫了一個ID,你可以再次運行它。
以下將MYTAB返回一行在整場的「n」的每一個間隙:
/* cs will contain 1 row for each contiguous sequence of integers in mytab.n
and will have the start of that chain.
ce will contain the end of that chain */
create temporary table cs (row int auto_increment primary key, n int);
create temporary table ce like cs;
insert into cs (n) select n from mytab where n-1 not in (select n from mytab) order by n;
insert into ce (n) select n from mytab where n+1 not in (select n from mytab) order by n;
select ce.n + 1 as bgap, cs.n - 1 as egap
from cs, ce where cs.row = ce.row + 1;
如果不是空白,你要連續鏈那麼最終的選擇應該是:
select cs.n as bchain, ce.n as echain from cs,ce where cs.row=ce.row;
第二個查詢''選擇cs.n as bchain,ce.n as echain from cs,ce where cs.row = ce.row;''顯示的聯接實際上存在較大的差距,但第一個工作正常。 – magdmartin
該解決方案是更好的,如果你需要包括第一元素爲1:
SELECT
1 AS gap_start,
MIN(e.id) - 1 AS gap_end
FROM
factura_entrada e
WHERE
NOT EXISTS(
SELECT
1
FROM
factura_entrada
WHERE
id = 1
)
LIMIT 1
UNION
SELECT
a.id + 1 AS gap_start,
MIN(b.id)- 1 AS gap_end
FROM
factura_entrada AS a,
factura_entrada AS b
WHERE
a.id < b.id
GROUP BY
a.id
HAVING
gap_start < MIN(b.id);
如果您使用的是MariaDB
你有一個更快的選擇
SELECT * FROM seq_1_to_50000 where seq not in (select col from table);
相關:http://stackoverflow.com/questions/3718229/stop-mysql-reusing-auto-increment-ids –
如果您使用INT作爲主鍵,則可以擁有20億條記錄。爲什麼要努力填補空白?你用完了數字嗎?我發現知道這些數字對應於添加記錄的順序是有好處的。 – minboost
也許你會遇到性能較低的麻煩,通過將主鍵類型更改爲BIGINT(如果INT提供的4個billon值太短),而不是嘗試在非常大的表上重用ID。 –