Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.80) (envelope-from ) id 1Zr91r-0005TZ-QX for pgsql-performance@arkaria.postgresql.org; Tue, 27 Oct 2015 18:31:27 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84) (envelope-from ) id 1Zr91r-0003nt-Be for pgsql-performance@arkaria.postgresql.org; Tue, 27 Oct 2015 18:31:27 +0000 Received: from makus.postgresql.org ([2001:4800:1501:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84) (envelope-from ) id 1Zr90D-0001t4-Iz for pgsql-performance@postgresql.org; Tue, 27 Oct 2015 18:29:45 +0000 Received: from mail-pa0-x229.google.com ([2607:f8b0:400e:c03::229]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.84) (envelope-from ) id 1Zr90B-0003yo-2S for pgsql-performance@postgresql.org; Tue, 27 Oct 2015 18:29:44 +0000 Received: by padhk11 with SMTP id hk11so230036386pad.1 for ; Tue, 27 Oct 2015 11:29:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:content-type:content-transfer-encoding:subject:message-id:date :to:mime-version; bh=knq1eJyD54Athm1F0g48svVUf1RTLk4ucQpdVU4c4RY=; b=uCQ7CX9kFiGfhiav/Dm9gS3PmFamZg1x0Cieoh4o6AQ2X61TWAD6rlrztYjN2gU6we CiJ6w4K/tN8v7veSk9pJex2jC07Q8gbuoCWjL20Hdq3XcBeNz8jdyy1yG4Jdkff3gGnA kb9+U31S5PERvvBT3SYZZqixl6DuijsAqgmQHWebjipH9r5vAbPCIaGoCLy2hYVp3UVO A0l2QRw+3Sy9+OB6TDIgWig0Jfd8SdRguErnvG0QNWrUTAIg5ZTWi34NVuvjJpy2BZDa jwJh0d4JY50qDhSImMMC7Ea2kNV8XK21mTC1HJdADhve3xYx/W5kRxYM+rMZ9/fuktZE sh8Q== X-Received: by 10.66.248.198 with SMTP id yo6mr16305066pac.96.1445970581761; Tue, 27 Oct 2015 11:29:41 -0700 (PDT) Received: from [10.2.52.121] ([207.66.146.242]) by smtp.gmail.com with ESMTPSA id ez1sm18597989pab.6.2015.10.27.11.29.36 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 27 Oct 2015 11:29:36 -0700 (PDT) From: GMail Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Subject: Partition Constraint Exclusion Limits Message-Id: <7C9FB5CD-7AF6-4167-8CCA-2075BD9091E2@gmail.com> Date: Tue, 27 Oct 2015 11:29:04 -0700 To: pgsql-performance@postgresql.org Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2104\)) X-Mailer: Apple Mail (2.2104) X-Pg-Spam-Score: -2.7 (--) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-performance Precedence: bulk Sender: pgsql-performance-owner@postgresql.org I have partitioned a large table in my PG database (6.7 billion rows!) by a= date column and in general constraint exclusion works well but only in rel= atively simple case when the partition key is specified exactly as created = in the CHECK constraint. I'm curious if there is a way to get it to work a= little more generally though. For example my CHECK constraint (see code below) specifying a hard-coded fi= eld value works well (#1 and #2). Specifying a function that returns a val= ue even though it is the appropriate type scans all of the partitions (#3) = unfortunately. Likewise any join, CTE, or sub-query expression, even for a= single row that returns the correct type also results in a scan of all of = the partitions.=20=20 I was curious if there was a way specifically to get #3 to work as the WHER= E predicate in this case is stored as an integer but the table itself is pa= rtitioned by the appropriate date type. I believe I could work around this= issue with dynamic sql in a function but there are lots of cases of this t= ype of simple conversion and I wanted to avoid the maintenance of creating = a function per query. It's also slightly surprising that queries that join with the appropriate t= ype (#4 & #5) also cause a full partition scan. Is there a work-around to = get constraint_exclusion to work in this case? -- constraint exclusion tests -- generate some data create schema if not exists ptest; set search_path=3Dptest; drop table if exists ptest.tbl cascade; create table if not exists tbl as select * from ( with a as ( select generate_series('2014-01-01'::date, now(), '1 day'::interval)::date= dt ), b as ( select generate_series(1, 1000) i ) select a.dt, b.i, md5((random()*4+5)::text) str from a cross join b ) c; -- create child partitions create table ptest.tbl_p2014(check (dt >=3D '2014-01-01'::date and dt < '20= 15-01-01'::date)) inherits (ptest.tbl); create table ptest.tbl_p2015(check (dt >=3D '2015-01-01'::date and dt < '20= 16-01-01'::date)) inherits (ptest.tbl); -- populate child partitions with pd as ( delete from only ptest.tbl where dt >=3D '2014-01-01'::date an= d dt < '2015-01-01'::date returning *)=20 insert into ptest.tbl_p2014 select * from pd; with pd as ( delete from only ptest.tbl where dt >=3D '2015-01-01'::date an= d dt < '2016-01-01'::date returning *)=20 insert into ptest.tbl_p2015 select * from pd; -- clean parent of any data truncate table only ptest.tbl; -- create dt field indexes create index i_tbl_dt on ptest.tbl(dt); create index i_tbl_dt_p2014 on ptest.tbl_p2014(dt); create index i_tble_dt_p2015 on ptest.tbl_p2015(dt); -- vacuum vacuum analyze verbose ptest.tbl; -- verify parent is empty and partitions have some data (estimated) select relname, n_live_tup from pg_stat_user_tables where relname like 'tbl= %' and schemaname =3D 'ptest' order by relname; -- check that partitions show in parent \d+ ptest.tbl -- force constraint_exclusion to partition set constraint_exclusion =3D partition; -- #1: works explain analyze select count(1) from ptest.tbl where dt =3D '2014-06-01'::d= ate; -- #2: works explain analyze select count(1) from ptest.tbl where dt =3D DATE '2014-06-0= 1'; -- #3: full scan (no constraint exclusion) explain analyze select count(1) from ptest.tbl where dt =3D to_date(201406:= :text||01::text, 'YYYYMMDD'); -- #4: full scan (no constraint exclusion) explain analyze select count(1) from ptest.tbl where dt =3D (select '2014-0= 6-01'::date); -- #5: full scan (no constraint exclusion) explain analyze with foo as (select '2014-06-01'::date dt) select count(1) from ptest.tbl inner join foo on (ptest.tbl.dt =3D foo.dt); --=20 Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-performance