这里的问题与我遇到的另一个问题有关...如何找到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。 –