Postgresql外键约束级联删除时容易忽略的问题

本文探讨了在PostgreSQL中,外键约束级联删除时可能遇到的性能问题。当表B的字段引用表A的主键,并设置级联删除,若表B的引用字段无索引,删除操作将进行顺序扫描,导致效率低下。解决方法是在表B的引用字段上创建索引,以加速级联删除过程。同时,文章提到了创建索引的优缺点,并分享了设置外键级联删除的SQL语句。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

外键约束用来实现表与表之间的参照完整性(referential integrity)。
外键约束是指一个引用表(referencing table)中的一个或多个引用字段(referencing column)必须与另一个被引用表(referenced table)中相应的被引用字段(referenced column)匹配,而且类型和值都必须匹配。
被引用表(referenced table)中的被引用列(referenced column)必须是一个非延迟的唯一约(unique key)束或者主键约束(primary key)。

外键约束可以设置级联删除。
设表B的字段y引用了表A的字段x(primary key or unique constraint),并设置了级联删除。当表A的某条记录删除时(x=x0),表B的某条记录(如果存在)也要被删除。
容易出现的问题:如果表B的字段y上没有建索引,删除表B记录时就会使用顺序扫描(Seq Scan)。当表B记录条数较多时顺序扫描会消耗较长时间。
解决方法:
表B的字段y增加索引。

1、创建索引的好处

–帮助用户提高查询速度 

–利用索引的唯一性来控制记录的唯一性 
–可以加速表与表之间的连接 
–降低查询中分组和排序的时间 
2、创建索引的坏处
–存储索引占用磁盘空间
–执行数据修改操作(INSERT、UPDATE、DELETE)产生索引维护

 

注意:没有索引的话  会全表查找,效率非常慢

索引可以建可以不建 
如果涉及查找的话,最好建索引。

上面引用原文:https://www.jianshu.com/p/fb1fab048584

https://blog.youkuaiyun.com/qq_29784441/article/details/80887544

附录:postgre所有外键设置级联删除语句

; WITH CTE AS (
SELECT
	KCU1.CONSTRAINT_NAME AS FK_CONSTRAINT_NAME,
	KCU1.TABLE_SCHEMA AS FK_SCHEMA_NAME,
	KCU1.TABLE_NAME AS FK_TABLE_NAME,
	KCU1.COLUMN_NAME AS FK_COLUMN_NAME,
	KCU1.ORDINAL_POSITION AS FK_ORDINAL_POSITION,
	KCU2.CONSTRAINT_NAME AS REFERENCED_CONSTRAINT_NAME,
	KCU2.TABLE_SCHEMA AS REFERENCED_SCHEMA_NAME,
	KCU2.TABLE_NAME AS REFERENCED_TABLE_NAME,
	KCU2.COLUMN_NAME AS REFERENCED_COLUMN_NAME,
	KCU2.ORDINAL_POSITION AS REFERENCED_ORDINAL_POSITION 
FROM
	INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC
	INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU1 ON KCU1.CONSTRAINT_CATALOG = RC.CONSTRAINT_CATALOG 
	AND KCU1.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA 
	AND KCU1.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
	INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU2 ON KCU2.CONSTRAINT_CATALOG = RC.UNIQUE_CONSTRAINT_CATALOG 
	AND KCU2.CONSTRAINT_SCHEMA = RC.UNIQUE_CONSTRAINT_SCHEMA 
	AND KCU2.CONSTRAINT_NAME = RC.UNIQUE_CONSTRAINT_NAME 
	AND KCU2.ORDINAL_POSITION = KCU1.ORDINAL_POSITION 
	) SELECT
	QUOTE_IDENT ( REFERENCED_TABLE_NAME ),
	FK_SCHEMA_NAME,
	FK_TABLE_NAME,
	FK_CONSTRAINT_NAME,
	FK_COLUMN_NAME,
	REFERENCED_COLUMN_NAME,
	'ALTER TABLE ' || QUOTE_IDENT ( FK_SCHEMA_NAME ) || '.' || QUOTE_IDENT ( FK_TABLE_NAME ) || ' ' || 'DROP CONSTRAINT ' || QUOTE_IDENT ( FK_CONSTRAINT_NAME ) || '; ' AS DropStmt,
'ALTER TABLE ' || QUOTE_IDENT ( FK_SCHEMA_NAME ) || '.' || QUOTE_IDENT ( FK_TABLE_NAME ) || ' 
ADD CONSTRAINT ' || QUOTE_IDENT ( FK_CONSTRAINT_NAME ) || ' 
FOREIGN KEY(' || string_agg ( FK_COLUMN_NAME, ', ' ) || ') 
' || '    REFERENCES ' || QUOTE_IDENT ( REFERENCED_SCHEMA_NAME ) || '.' || QUOTE_IDENT ( REFERENCED_TABLE_NAME ) || '(' || string_agg ( REFERENCED_COLUMN_NAME, ', ' ) || ') 
ON DELETE CASCADE 
	; ' AS CreateStmt,
'create index ' || QUOTE_IDENT ( FK_TABLE_NAME ) || '__' || string_agg ( FK_COLUMN_NAME, ', ' ) || '__index  ON ' || QUOTE_IDENT ( FK_SCHEMA_NAME ) || '.' || QUOTE_IDENT ( FK_TABLE_NAME ) || ' ' || '(' || string_agg ( FK_COLUMN_NAME, ', ' ) || ') ' || '; ' AS createIndexStmt 
FROM
	CTE 
GROUP BY
	QUOTE_IDENT ( REFERENCED_TABLE_NAME ),
	FK_SCHEMA_NAME,
	FK_TABLE_NAME,
	FK_CONSTRAINT_NAME,
	FK_COLUMN_NAME,
	REFERENCED_COLUMN_NAME,
	REFERENCED_SCHEMA_NAME,
	REFERENCED_TABLE_NAME 
ORDER BY
	FK_SCHEMA_NAME,
	FK_TABLE_NAME;

其中分别通过DropStmt列和CreateStmt列,进行外键删除和重建外键并设置级联删除操作

通过createIndexStmt列创建外键索引,提高级联删除操作时的效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值