Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sPrNl-006gcL-Jj for pgsql-general@arkaria.postgresql.org; Fri, 05 Jul 2024 22:26:21 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1sPrNi-00EsMT-9U for pgsql-general@arkaria.postgresql.org; Fri, 05 Jul 2024 22:26:18 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sPrNh-00EsMK-UJ for pgsql-general@lists.postgresql.org; Fri, 05 Jul 2024 22:26:18 +0000 Received: from mail-lj1-x22d.google.com ([2a00:1450:4864:20::22d]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1sPrNg-000cev-Pz for pgsql-general@lists.postgresql.org; Fri, 05 Jul 2024 22:26:18 +0000 Received: by mail-lj1-x22d.google.com with SMTP id 38308e7fff4ca-2ee7885aa5fso22455551fa.1 for ; Fri, 05 Jul 2024 15:26:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1720218374; x=1720823174; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=QimVEMItvJKCYKYlfIwsljVaGo82aK+yUlceIkp1egw=; b=Xc+2fpgIhL72CeIM04gD+YCP3zNpxZAEeOeCro2j0tc43fRrOmcAoW5jSmcaGSMjye rFRfJsnWRAXGB3eqowgBKa9P5OPAaoV/nPTt6zANjdqoF2PxsjyMWTzQ/FerbD29HFRw HszkKNRG5kpjt2FPkyfJK68kCeDMH5guPz88cq8MWFucqLRt8DocxxiNbvNIn9Zt5qWP TO/HidS9wR2lRxBfcTmxiysOBDJPwVoQgNbgudH55+qWXzf4GTIUUhW3itNxAwKeGCyf vz1RL9Hy8s/M1uPWoETNnhFbpLtLrF631gihW8/QQq86m9fVPNuQY5TZCXPBIJ/7Z4uM BX5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720218374; x=1720823174; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=QimVEMItvJKCYKYlfIwsljVaGo82aK+yUlceIkp1egw=; b=plCo88V1jMLvRvMsaNVn4k7yp/EVTdEulNMVphlTSJHAZ75e3/N9l81V//SKqfVwwG g/qAZ20upua9gqjY0o5CRtK5qcWk+iLwNNggRd/AMUAc2Kk+m/bJ3YrifD6fruIEW+wY vdzxV4vf6ecPJxrex1PdUbhUgcroiFWVXy9bKlE+8yeOWFIeWH4J4dnUkqP0Ccu6N8cf p+HpIAV9S5k+AW8xHdtbjav5b8lFRfuXBwTz73czd/LypVnwi65htQH523bpBcdnIGgO VhIg5gjkP0M2H7RYeu66oSzY4h2qu7mCfOW7NVQIJezUrcvanzepEF0OPYWck9cUtVYa 2TOg== X-Gm-Message-State: AOJu0YySsNFHhORVO1b9wuQS6zDIaXt0rk/rGUEazB6zo0V0Ezo8B012 8GQn/Qhysgfmue2E1azKA2MNOivYNvi4JHs+JXns1bvbTDQ66Cg4x8E3NyS+oGlTpQyGRxK9ioP e2mIkHIum28QnCCG8kuvSZBomLeU= X-Google-Smtp-Source: AGHT+IHzVPrHhstP/XTy/vW6hGhBco8+SN6/bntpgGw1lv1F8eja1xdc4bquMYe1V8bsRYFOYU3sQ8selzz5nbdUnTE= X-Received: by 2002:a05:6512:3da3:b0:52c:db80:d694 with SMTP id 2adb3069b0e04-52ea0626e92mr4920225e87.20.1720218373972; Fri, 05 Jul 2024 15:26:13 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: David Rowley Date: Sat, 6 Jul 2024 10:26:01 +1200 Message-ID: Subject: Re: Planning of sub partitions To: Matt Hughes Cc: pgsql-general@lists.postgresql.org Content-Type: text/plain; charset="UTF-8" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Sat, 6 Jul 2024 at 03:24, Matt Hughes wrote: > -- 4. uses all partitions; should exclude event_closed_y2024_m02 > explain select * from event > where > cleared is false OR > (cleared is true and date_raised > '2024-01-01' AND date_raised < '2024-01-02'); > QUERY PLAN > ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- > Append (cost=0.00..110.91 rows=2322 width=25) > -> Seq Scan on event_open event_1 (cost=0.00..33.10 rows=774 width=25) > Filter: ((cleared IS FALSE) OR ((date_raised > '2024-01-01 00:00:00'::timestamp without time zone) AND (date_raised < '2024-01-02 00:00:00'::timestamp without time zone))) > -> Seq Scan on event_closed_y2024_m01 event_2 (cost=0.00..33.10 rows=774 width=25) > Filter: ((cleared IS FALSE) OR ((date_raised > '2024-01-01 00:00:00'::timestamp without time zone) AND (date_raised < '2024-01-02 00:00:00'::timestamp without time zone))) > -> Seq Scan on event_closed_y2024_m02 event_3 (cost=0.00..33.10 rows=774 width=25) > Filter: ((cleared IS FALSE) OR ((date_raised > '2024-01-01 00:00:00'::timestamp without time zone) AND (date_raised < '2024-01-02 00:00:00'::timestamp without time zone))) > > > Is this a bug? Query 4 is just a union of queries 2/3 which pick the right partitions. Do you see anything else wrong with this approach? I'm not sure I'd want to class it as a bug. I think we could call it a limitation of pruning with multiple levels of partitioned tables. The problem is that pruning for the "event" table matches both of its partitions; event_open and event_closed. Since event_closed is also a partitioned table, pruning is also executed on that partitioned table. When that pruning is done, it processes the WHERE clause conditions and only finds date_raised conditions in an OR branch, therefore it cannot prune since the other OR does not contain the same conditions. There is some code in gen_partprune_steps() that makes use of the partitioning qual of the partitioned table, but the comment there explains that it's only intended for DEFAULT partitions in cases when partition keys are shared between a partitioned table and its child partitioned table. Adding the partitioning qual in this case wouldn't help since the partition keys are different at both levels. You could get what you want using two columns in a RANGE partitioned table, such as: create table event ( id uuid not null, cleared boolean not null, date_raised timestamp without time zone not null, date_cleared timestamp without time zone, primary key (id, date_raised, cleared) ) PARTITION BY RANGE (cleared, date_raised); CREATE TABLE event_open PARTITION OF event FOR VALUES FROM (false, MINVALUE) TO (false, MAXVALUE); CREATE TABLE event_closed_y2024_m01 PARTITION OF event FOR VALUES FROM (true,'2024-01-01') to (true,'2024-02-01'); CREATE TABLE event_closed_y2024_m02 PARTITION OF event FOR VALUES FROM (true,'2024-02-01') to (true,'2024-03-01'); explain select * from event where not cleared OR (cleared and date_raised > '2024-01-01' AND date_raised < '2024-01-02'); David