想象一下关于猫主人的下表。
drop table if exists owners cascade;
create table owners(
id bigint primary key generated always as identity ,
name text not null
)
;
insert into owners(name)
select random()::text from generate_series(1,20000);
--insert 200,000 owners records
Run Code Online (Sandbox Code Playgroud)
当我删除一些所有者记录时,速度非常快:
delete from owners
where id %10 = 0;
Run Code Online (Sandbox Code Playgroud)
85 毫秒内影响了 20000 行
现在我添加一个名为“cats”的表,它指的是所有者:
drop table if exists cats;
create table cats(
id serial primary key ,
name varchar(20000) not null,
owner_id int not null references owners(id)
);
--insert 1bn cats records
insert into cats(name, owner_id)
select
random()::text,
owners.id
from generate_series(1,10), owners;
Run Code Online (Sandbox Code Playgroud)
让我们删除一些所有者,但首先我们必须删除这些所有者“拥有”的猫:
--delete the records in cats so we don't get a foreign key constraint violation
delete from cats
where owner_id %10 = 1;
---now we do the same delete on owners as we did before
delete from owners
where id %10 = 1;
Run Code Online (Sandbox Code Playgroud)
在 25 秒 828 毫秒内影响了 2000 行
为什么所有者的第二次删除比我们没有 cat 表时慢 5000 倍?
这是检查cats
在 DELETE 期间表是否仍然引用所有者。检查基本上是使用select * from cats where owner_id = ?
您删除的每个所有者完成的。
您可以通过在外键列上创建索引来加快检查速度:
create index on cats (owner_id);
Run Code Online (Sandbox Code Playgroud)