PostgresSQL ON DELETE级联的性能



我有一个关于ON DELETE CASCADE性能的问题。我想知道为什么要花这么长时间。出于本主题的目的,我将实际案例简化为如下所示的模式:

CREATE TABLE IF NOT EXISTS public.items
(
id uuid NOT NULL,
name text COLLATE pg_catalog."default",
CONSTRAINT items_pk PRIMARY KEY (id)
);
CREATE TABLE IF NOT EXISTS public.links
(
parent uuid,
child uuid,
CONSTRAINT links_parent_fk FOREIGN KEY (parent)
REFERENCES public.items (id) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT links_child_fk FOREIGN KEY (child)
REFERENCES public.items (id) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS parent_idx
ON public.links USING btree
(parent ASC NULLS LAST);
CREATE INDEX IF NOT EXISTS child_idx
ON public.links USING btree
(child ASC NULLS LAST);

CREATE EXTENSION "uuid-ossp";

和数据可以生成:

INSERT INTO public.items
SELECT uuid_generate_v4 (), 'item_' || i
FROM generate_series(1, 134001) AS i;

INSERT INTO links
SELECT (SELECT id FROM public.items WHERE name='item_1'), id FROM public.items;

简单地说,数据库包含两个表。表items包含一个项目列表(标识符和名称列),表links定义了项目之间的关系(parent <->孩子)。在本例中,所有项(子项)都属于名为"item_1"(父项)的项。

我调用一个查询来删除所有分配给parent的子节点:

BEGIN;
EXPLAIN ANALYZE DELETE FROM public.items where id in (SELECT child FROM public.links WHERE parent = (SELECT id FROM public.items WHERE name='item_1'));
ROLLBACK;

从执行计划中我们可以读到:
"触发约束links_parent_fk: time=10451.471 calls=134001">
"触发约束links_child_fk: time=2962.035 calls=134001">

问题是为什么触发约束links_parent_fk消耗大量时间?

我尝试在links表的列之间交换数据。之后,links_child_fk的触发时间为~10秒,links_parent_fk的触发时间为~3秒。我很好奇为什么这个delete级联的执行之间有这样的差异?

PostgreSQL version: 12.4 and 13.9.

PostgreSQL在Linux上肯定会比在Windows上运行得更快作为一个写了Windows版本的人来说…)它是为Unix风格的体系结构设计,并实现了相同的功能架构,这意味着它做了很多事情Windows的设计并不是为了做得好。它工作得很好,但它没有

Magnus Hagander

https://www.postgresql.eu/events/pgconfeu2019/sessions/session/2664/slides/211/PostgreSQL%20under%20Windows.pdf

我在Azure上使用Postgres(当时是windows Postgres)时看到了这一点。我认为他们已经/正在迁移到Linux postgres,因为性能问题。

因此,我认为在windows上测试Postgres的性能并在性能重要的情况下在windows上运行Postgres是没有意义的,最好使用不同的操作系统或不同的RDBMS。

最新更新