Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1htY5D-0004sF-RM for pgsql-performance@arkaria.postgresql.org; Fri, 02 Aug 2019 13:58:59 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1htY5C-0006kg-Gl for pgsql-performance@arkaria.postgresql.org; Fri, 02 Aug 2019 13:58:58 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1htY5C-0006hv-7W for pgsql-performance@lists.postgresql.org; Fri, 02 Aug 2019 13:58:58 +0000 Received: from mout.kundenserver.de ([217.72.192.74]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1htY59-00078j-93 for pgsql-performance@lists.postgresql.org; Fri, 02 Aug 2019 13:58:57 +0000 Received: from [10.8.0.6] ([185.40.248.10]) by mrelayeu.kundenserver.de (mreue106 [212.227.15.145]) with ESMTPSA (Nemesis) id 1MVMNF-1hkRh64BHz-00SRC9 for ; Fri, 02 Aug 2019 15:58:52 +0200 X-Mozilla-News-Host: news://news.gmane.org:119 To: pgsql-performance@lists.postgresql.org From: Thomas Kellerer Subject: Strange runtime partition pruning behaviour with 11.4 Message-ID: <29b2f4c6-987b-d364-2e1d-bbd479d06da2@gmx.net> Date: Fri, 2 Aug 2019 15:58:51 +0200 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.23) Gecko/20090812 Thunderbird/2.0.0.23 Mnenhy/0.7.6.666 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Language: en-GB Content-Transfer-Encoding: 7bit X-Provags-ID: V03:K1:PtvkDBWGtD7LZs5iPnmA20HUH9j+Bu16Bu1SKcmdfysPLbSjnpO 6UFGxL+ILQWjy5bgD3YlULwkxPbNGxbBlAtwwqAao7sUZueStEIR2V0XRXynPhHA669/nhG oZ7nVg12P00rNcA49aph5gerFKJqtMFjVnHTBUyipFtRTD/fXV0MXjwVzSKC2iCIb/OQ4EO /JvVbwECTOOMnms3XEtjg== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:EZHxu5aYwgE=:Nn15Vf/xG+JLoJh4DeMd1x wkpdxTu3s8PKdM40fdJaYG6W0jX5VNLL3UcZtyJ0HU0EbaLoWjdFSviFxzhPHqtilpk+QW2P4 PrtAcc8BdouS+eRUC1mnvGhy07/rBZP3Mz/X3FWP2sqJuXRCTkaKMD5rvtDsUOj/EFuxsZyoq OEW6hgs44Udcjt0gda/4gwjWEBQIYUUM9HyYvNit+9iE4bQm8wkPcXxOP6Avd+4PjqMSaIxpR 5V8FYg9lzi93Y1rAc+fUv6z3GbyTEKEk1tBoYurJ12tjFqCb8T1f1eTL0suLFwbp9ggDqIcvI HoXW9fESie/gl5jYNmR2rj4yjELhW9rU2WxWiO0bznq9vqsaoWJS8gWrPECTJE6oXlujcr853 zpozZkljd7zH++VSeYzu2847Ib0VRADFh1MPMNFtf7s7OJ0lmbrn/qvdqAvstP97cursilQfy +r3kgr2wUHBYPtdFx4Zn4UdgkJAdSh/hKY8U1SrnDyI9cdjK80LVMOcvKKFikReLsDuBy0yXY 6IZy77JaHcXTXx4SasQKWeCXkuajtEk0WRoQRSdCd1hH9NP9exCdwspx9lYso8K0TI0PbkYL9 aAqwvnafIBf4YeMg0AMHQ4njm2THUSmWon8jy9qjt+sf/mSH6KTj43+vy4o87tDT6ljpEnymQ wYE1sHWWDMY57n4OuHraytWjp7AgNk0QLFq623ZQRobduOQlj5qCugr2jfe0sB67V73xtQvMN GoYLeo52yGA387uJQAuKxmmudXv0ThXmcXr083Tv/k07ga71yb7IgQv9BhI= List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk I stumbled across this question on SO: https://stackoverflow.com/questions/56517852 Disregarding the part about Postgres 9.3, the example for Postgres 11 looks a bit confusing. There is a script to setup test data in that question: ==== start of script ==== create table foo ( foo_id integer not null, foo_name varchar(10), constraint foo_pkey primary key (foo_id) ); insert into foo (foo_id, foo_name) values (1, 'eeny'), (2, 'meeny'), (3, 'miny'), (4, 'moe'), (5, 'tiger'), (6, 'toe'); create table foo_bar_baz ( foo_id integer not null, bar_id integer not null, baz integer not null, constraint foo_bar_baz_pkey primary key (foo_id, bar_id, baz), constraint foo_bar_baz_fkey1 foreign key (foo_id) references foo (foo_id) ) partition by range (foo_id) ; create table if not exists foo_bar_baz_0 partition of foo_bar_baz for values from (0) to (1); create table if not exists foo_bar_baz_1 partition of foo_bar_baz for values from (1) to (2); create table if not exists foo_bar_baz_2 partition of foo_bar_baz for values from (2) to (3); create table if not exists foo_bar_baz_3 partition of foo_bar_baz for values from (3) to (4); create table if not exists foo_bar_baz_4 partition of foo_bar_baz for values from (4) to (5); create table if not exists foo_bar_baz_5 partition of foo_bar_baz for values from (5) to (6); with foos_and_bars as ( select ((random() * 4) + 1)::int as foo_id, bar_id::int from generate_series(0, 1499) as t(bar_id) ), bazzes as ( select baz::int from generate_series(1, 1500) as t(baz) ) insert into foo_bar_baz (foo_id, bar_id, baz) select foo_id, bar_id, baz from bazzes as bz join foos_and_bars as fab on mod(bz.baz, fab.foo_id) = 0; ==== end of script ==== I see the some strange behaviour similar to to what is reported in the comments to that question: When I run the test query immediately after populating the tables with the sample data: explain analyze select count(*) from foo_bar_baz as fbb join foo on fbb.foo_id = foo.foo_id where foo.foo_name = 'eeny' I do see an "Index Only Scan .... (never executed)" in the plan for the irrelevant partitions: https://explain.depesz.com/s/AqlE However once I run "analyze foo_bar_baz" (or "vacuum analyze"), Postgres chooses to do a "Parallel Seq Scan" for each partition: https://explain.depesz.com/s/WwxE Why does updating the statistics mess up (runtime) partition pruning? I played around with random_page_cost and that didn't change anything. I tried to create extended statistics on "foo(id, name)" so that the planner would no, that there is only one name per id. No change. I saw the above behaviour when running this on Windows 10 (my Laptop) or CentOS 7 (a test environment on a VM) On the CentOS server default_statistics_target is set to 100, on my laptop it is set to 1000 In both cases the Postgres version was 11.4 Any ideas? Thomas