我有一个关于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。