我有大约 1000 万行的表,id
列是primary key
.
然后我删除所有行where id > 10
。表中只剩下 10 行。
现在,当我运行查询时SELECT id FROM tablename
,执行时间大约为 1.2 - 1.5 秒。
但SELECT id FROM tablename where id = x
只需要 10 - 11 毫秒。
为什么SELECT
只有 10 行的第一个这么慢?
我有大约 1000 万行的表,id
列是primary key
.
然后我删除所有行where id > 10
。表中只剩下 10 行。
现在,当我运行查询时SELECT id FROM tablename
,执行时间大约为 1.2 - 1.5 秒。
但SELECT id FROM tablename where id = x
只需要 10 - 11 毫秒。
为什么SELECT
只有 10 行的第一个这么慢?
主要原因是Postgres 的 MVCC 模型,其中删除的行被保留,直到系统可以确定事务没有回滚并且死行不再对任何并发事务可见。只有这样,死行才能被物理删除VACUUM
- 或更彻底VACUUM FULL
。
有关的:
您的简单查询SELECT id FROM tablename
- 如果DELETE
在 autovacuum 可以启动之后和之前立即运行 - 仍然会找到 1000 万行并且必须检查可见性,只是为了排除其中的大部分。
您的第二个查询SELECT id FROM tablename where id = x
可以使用主键索引,并且只需要从(以前的)大表中读取单个数据页。这种查询在很大程度上不受表的总大小的影响。
可能有一种(更)更有效的方法来删除几乎所有 1000 万行: