{"id":34811,"date":"2024-09-25T13:11:05","date_gmt":"2024-09-25T11:11:05","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/?p=34811"},"modified":"2024-09-25T13:11:08","modified_gmt":"2024-09-25T11:11:08","slug":"postgresql-partitioned-tables-and-optimizer-statistics","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/postgresql-partitioned-tables-and-optimizer-statistics\/","title":{"rendered":"PostgreSQL: Partitioned tables and optimizer statistics"},"content":{"rendered":"\n<p>The PostgreSQL optimizer relies on accurate statistics for finding and executing the most efficient plan for a given statement. Wrong or bad statistics usually lead to sub optimal execution plans and this usually is bad performance wise. This is not only true with PostgreSQL, all databases systems which use a cost based optimizer rely on statistics. Usually, you don&#8217;t need to care about the statistics, as PostgreSQL will collect them automatically based on the amount of changes which happened on a table since the last collection of the statistics. In this post we&#8217;ll look at how this works in general and then we&#8217;ll go into more details when it comes to partitioned tables.<\/p>\n\n\n\n<p>Lets start by creating a simple table and populate it with one million rows:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [1,3]; title: ; notranslate\" title=\"\">\npostgres=# create table x ( a int, b text );\nCREATE TABLE\npostgres=# insert into x select i, &#039;aaa&#039; from generate_series(1,1000000) i;\nINSERT 0 1000000\n<\/pre><\/div>\n\n\n<p>If you ask for the available statistics in <a href=\"https:\/\/www.postgresql.org\/docs\/current\/view-pg-stats.html\">pg_stats<\/a> right after population the table, you will most probably not see anything yet:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [1]; title: ; notranslate\" title=\"\">\npostgres=# select count(*) from pg_stats where tablename = &#039;x&#039;;\n count \n-------\n     0\n(1 row)\n<\/pre><\/div>\n\n\n<p>The reason is, that autovacuum (which is also responsible for automatically collecting the statistics) will sleep some time before it wakes up and checks if anything needs to be done. By default this is one minute:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [1]; title: ; notranslate\" title=\"\">\npostgres=# show autovacuum_naptime;\n autovacuum_naptime \n--------------------\n 1min\n(1 row)\n<\/pre><\/div>\n\n\n<p>After a maximum of one minute, you&#8217;ll see that statistics are available:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [1]; title: ; notranslate\" title=\"\">\npostgres=# select count(*) from pg_stats where tablename = &#039;x&#039;;\n count \n-------\n     2\n(1 row)\n<\/pre><\/div>\n\n\n<p>We&#8217;re not going to look at what those statistics are in detail in this post, just remember that autovacuum will collect them by default. When it will do this, depends on the following parameters:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [1,7]; title: ; notranslate\" title=\"\">\npostgres=# show autovacuum_analyze_scale_factor;\n autovacuum_analyze_scale_factor \n---------------------------------\n 0.1\n(1 row)\n\npostgres=# show autovacuum_analyze_threshold;\n autovacuum_analyze_threshold \n------------------------------\n 50\n(1 row)\n<\/pre><\/div>\n\n\n<p>For our table &#8216;x&#8217; this means we would need to change approximately 10 percent of the table for the automatic gathering of statistics to kick in, and this can easily be demonstrated (again, you might need to wait up to a minute to see last_autoanalyze updated in <a href=\"https:\/\/www.postgresql.org\/docs\/current\/monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW\">pg_stat_all_tables<\/a>):<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [1,4]; title: ; notranslate\" title=\"\">\npostgres=# update x set b =&#039;bbb&#039; where a &lt; 110000;\nUPDATE 109999\n-- Wait up to a minute\npostgres=# select last_autoanalyze from pg_stat_all_tables where relname = &#039;x&#039;;\n       last_autoanalyze        \n-------------------------------\n 2024-09-25 10:49:06.095124+02\n(1 row)\n<\/pre><\/div>\n\n\n<p>For partitioned tables this works the same for the partitions, but not for the partitioned table itself. Before we look at why it is like this, lets create another simple test:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [1,3,5,7]; title: ; notranslate\" title=\"\">\npostgres=# create table y ( a int, b text ) partition by list (b);\nCREATE TABLE\npostgres=# create table y_1 partition of y for values in (&#039;a&#039;);\nCREATE TABLE\npostgres=# create table y_2 partition of y for values in (&#039;b&#039;);\nCREATE TABLE\npostgres=# \\d+ y\n                                      Partitioned table &quot;public.y&quot;\n Column |  Type   | Collation | Nullable | Default | Storage  | Compression | Stats target | Description \n--------+---------+-----------+----------+---------+----------+-------------+--------------+-------------\n a      | integer |           |          |         | plain    |             |              | \n b      | text    |           |          |         | extended |             |              | \nPartition key: LIST (b)\nPartitions: y_1 FOR VALUES IN (&#039;a&#039;),\n            y_2 FOR VALUES IN (&#039;b&#039;)\n<\/pre><\/div>\n\n\n<p>This is a simple list partitioned table, containing two partitions. If we add some data PostgreSQL will take care of collecting the statistics, but there is a surprise:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [1,3,6]; title: ; notranslate\" title=\"\">\npostgres=# insert into y select i, &#039;a&#039; from generate_series(1,1000000) i;\nINSERT 0 1000000\npostgres=# insert into y select i, &#039;b&#039; from generate_series(1,1000000) i;\nINSERT 0 1000000\n-- Wait up to a minute\npostgres=# select relname,last_autoanalyze from pg_stat_all_tables where relname like &#039;y%&#039;;\n relname |       last_autoanalyze        \n---------+-------------------------------\n y       | \n y_1     | 2024-09-25 11:22:07.463249+02\n y_2     | 2024-09-25 11:22:07.180454+02\n<\/pre><\/div>\n\n\n<p>We see that statistics have been collected on the individual partitions, but not on the partitioned table itself. The reason is, that the amount of changes are not tracked on the partitioned table, but only on the partitions:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [1,9,11]; title: ; notranslate\" title=\"\">\npostgres=# select relname,last_autoanalyze,n_mod_since_analyze from pg_stat_all_tables where relname like &#039;y%&#039;;\n relname |       last_autoanalyze        | n_mod_since_analyze \n---------+-------------------------------+---------------------\n y       |                               |                   0\n y_1     | 2024-09-25 11:22:07.463249+02 |                   0\n y_2     | 2024-09-25 11:22:07.180454+02 |                   0\n(3 rows)\n\npostgres=# update y set b = &#039;a&#039; where a &lt; 1000;\nUPDATE 1998\npostgres=# select relname,last_autoanalyze,n_mod_since_analyze from pg_stat_all_tables where relname like &#039;y%&#039;;\n relname |       last_autoanalyze        | n_mod_since_analyze \n---------+-------------------------------+---------------------\n y       |                               |                   0\n y_1     | 2024-09-25 11:22:07.463249+02 |                1998\n y_2     | 2024-09-25 11:22:07.180454+02 |                 999\n(3 rows)\n<\/pre><\/div>\n\n\n<p>As the partitioned table itself does not contain any rows, there is nothing to track here. The consequence is, that there are no statistics at the partitioned table level, only on the partitions:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [1]; title: ; notranslate\" title=\"\">\npostgres=# select tablename,attname,null_frac,n_distinct from pg_stats where tablename like &#039;y%&#039;;\n tablename | attname | null_frac | n_distinct \n-----------+---------+-----------+------------\n y_2       | a       |         0 |         -1\n y_2       | b       |         0 |          1\n y_1       | a       |         0 |         -1\n y_1       | b       |         0 |          1\n(4 rows)\n\n<\/pre><\/div>\n\n\n<p>If you want to have statistics on the partitioned table as well, you have to do that manually:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [1,3]; title: ; notranslate\" title=\"\">\npostgres=# analyze y;\nANALYZE\npostgres=# select tablename,attname,null_frac,n_distinct from pg_stats where tablename like &#039;y%&#039;;\n tablename | attname | null_frac | n_distinct  \n-----------+---------+-----------+-------------\n y         | a       |         0 |   -0.525885\n y         | b       |         0 |           2\n y_1       | a       |         0 | -0.99563634\n y_1       | b       |         0 |           1\n y_2       | a       |         0 |          -1\n y_2       | b       |         0 |           1\n(6 rows)\n<\/pre><\/div>\n\n\n<p>Just be aware that this will not only collect the statistics for the partitioned table but also for all the partitions:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [1]; title: ; notranslate\" title=\"\">\npostgres=# select relname,last_analyze from pg_stat_all_tables where relname like &#039;y%&#039;;\n relname |         last_analyze          \n---------+-------------------------------\n y       | 2024-09-25 11:34:53.503998+02\n y_1     | 2024-09-25 11:34:53.527063+02\n y_2     | 2024-09-25 11:34:53.545629+02\n(3 rows)\n<\/pre><\/div>\n\n\n<p>If your partitions are huge, this can take quite some time and there is not much you can do about it. There was a patch <a href=\"https:\/\/git.postgresql.org\/gitweb\/?p=postgresql.git;a=commitdiff;h=62ddf7ee9a399e0b9624412fc482ed7365e38958\">committed<\/a> yesterday to address this for PostgreSQL 18. When it will be released, probably end of September or beginning of October next  year, you can ask <a href=\"https:\/\/www.postgresql.org\/docs\/current\/sql-analyze.html\">analyze<\/a> to only collect the statistics on the partitioned table:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [1,3]; title: ; notranslate\" title=\"\">\npostgres=# analyze only y;\nANALYZE\npostgres=# select relname,last_analyze from pg_stat_all_tables where relname like &#039;y%&#039;;\n relname |         last_analyze          \n---------+-------------------------------\n y       | 2024-09-25 11:41:00.619087+02\n y_1     | 2024-09-25 11:34:53.527063+02\n y_2     | 2024-09-25 11:34:53.545629+02\n(3 rows)\n\npostgres=# \n<\/pre><\/div>\n\n\n<p>This does not solve the problem of missing statistics on partitioned tables, but it avoids redundant work as statistics on the partitions will be collected automatically anyway.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The PostgreSQL optimizer relies on accurate statistics for finding and executing the most efficient plan for a given statement. Wrong or bad statistics usually lead to sub optimal execution plans and this usually is bad performance wise. This is not only true with PostgreSQL, all databases systems which use a cost based optimizer rely on [&hellip;]<\/p>\n","protected":false},"author":29,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[229],"tags":[77],"type_dbi":[],"class_list":["post-34811","post","type-post","status-publish","format-standard","hentry","category-database-administration-monitoring","tag-postgresql"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>PostgreSQL: Partitioned tables and optimizer statistics - dbi Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dbi-services.com\/blog\/postgresql-partitioned-tables-and-optimizer-statistics\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"PostgreSQL: Partitioned tables and optimizer statistics\" \/>\n<meta property=\"og:description\" content=\"The PostgreSQL optimizer relies on accurate statistics for finding and executing the most efficient plan for a given statement. Wrong or bad statistics usually lead to sub optimal execution plans and this usually is bad performance wise. This is not only true with PostgreSQL, all databases systems which use a cost based optimizer rely on [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/postgresql-partitioned-tables-and-optimizer-statistics\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2024-09-25T11:11:05+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-09-25T11:11:08+00:00\" \/>\n<meta name=\"author\" content=\"Daniel Westermann\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@westermanndanie\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Daniel Westermann\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/postgresql-partitioned-tables-and-optimizer-statistics\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/postgresql-partitioned-tables-and-optimizer-statistics\/\"},\"author\":{\"name\":\"Daniel Westermann\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66\"},\"headline\":\"PostgreSQL: Partitioned tables and optimizer statistics\",\"datePublished\":\"2024-09-25T11:11:05+00:00\",\"dateModified\":\"2024-09-25T11:11:08+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/postgresql-partitioned-tables-and-optimizer-statistics\/\"},\"wordCount\":550,\"commentCount\":0,\"keywords\":[\"PostgreSQL\"],\"articleSection\":[\"Database Administration &amp; Monitoring\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/postgresql-partitioned-tables-and-optimizer-statistics\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/postgresql-partitioned-tables-and-optimizer-statistics\/\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/postgresql-partitioned-tables-and-optimizer-statistics\/\",\"name\":\"PostgreSQL: Partitioned tables and optimizer statistics - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\"},\"datePublished\":\"2024-09-25T11:11:05+00:00\",\"dateModified\":\"2024-09-25T11:11:08+00:00\",\"author\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/postgresql-partitioned-tables-and-optimizer-statistics\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/postgresql-partitioned-tables-and-optimizer-statistics\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/postgresql-partitioned-tables-and-optimizer-statistics\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/www.dbi-services.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"PostgreSQL: Partitioned tables and optimizer statistics\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66\",\"name\":\"Daniel Westermann\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g\",\"caption\":\"Daniel Westermann\"},\"description\":\"Daniel Westermann is Principal Consultant and Technology Leader Open Infrastructure at dbi services. He has more than 15 years of experience in management, engineering and optimization of databases and infrastructures, especially on Oracle and PostgreSQL. Since the beginning of his career, he has specialized in Oracle Technologies and is Oracle Certified Professional 12c and Oracle Certified Expert RAC\/GridInfra. Over time, Daniel has become increasingly interested in open source technologies, becoming \u201cTechnology Leader Open Infrastructure\u201d and PostgreSQL expert. \u00a0Based on community or EnterpriseDB tools, he develops and installs complex high available solutions with PostgreSQL. He is also a certified PostgreSQL Plus 9.0 Professional and a Postgres Advanced Server 9.4 Professional. He is a regular speaker at PostgreSQL conferences in Switzerland and Europe. Today Daniel is also supporting our customers on AWS services such as AWS RDS, database migrations into the cloud, EC2 and automated infrastructure management with AWS SSM (System Manager). He is a certified AWS Solutions Architect Professional. Prior to dbi services, Daniel was Management System Engineer at LC SYSTEMS-Engineering AG in Basel. Before that, he worked as Oracle Developper &amp;\u00a0Project Manager at Delta Energy Solutions AG in Basel (today Powel AG). Daniel holds a diploma in Business Informatics (DHBW, Germany). His branch-related experience mainly covers the pharma industry, the financial sector, energy, lottery and telecommunications.\",\"sameAs\":[\"https:\/\/x.com\/westermanndanie\"],\"url\":\"https:\/\/www.dbi-services.com\/blog\/author\/daniel-westermann\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"PostgreSQL: Partitioned tables and optimizer statistics - dbi Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dbi-services.com\/blog\/postgresql-partitioned-tables-and-optimizer-statistics\/","og_locale":"en_US","og_type":"article","og_title":"PostgreSQL: Partitioned tables and optimizer statistics","og_description":"The PostgreSQL optimizer relies on accurate statistics for finding and executing the most efficient plan for a given statement. Wrong or bad statistics usually lead to sub optimal execution plans and this usually is bad performance wise. This is not only true with PostgreSQL, all databases systems which use a cost based optimizer rely on [&hellip;]","og_url":"https:\/\/www.dbi-services.com\/blog\/postgresql-partitioned-tables-and-optimizer-statistics\/","og_site_name":"dbi Blog","article_published_time":"2024-09-25T11:11:05+00:00","article_modified_time":"2024-09-25T11:11:08+00:00","author":"Daniel Westermann","twitter_card":"summary_large_image","twitter_creator":"@westermanndanie","twitter_misc":{"Written by":"Daniel Westermann","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/postgresql-partitioned-tables-and-optimizer-statistics\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/postgresql-partitioned-tables-and-optimizer-statistics\/"},"author":{"name":"Daniel Westermann","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66"},"headline":"PostgreSQL: Partitioned tables and optimizer statistics","datePublished":"2024-09-25T11:11:05+00:00","dateModified":"2024-09-25T11:11:08+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/postgresql-partitioned-tables-and-optimizer-statistics\/"},"wordCount":550,"commentCount":0,"keywords":["PostgreSQL"],"articleSection":["Database Administration &amp; Monitoring"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/postgresql-partitioned-tables-and-optimizer-statistics\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/postgresql-partitioned-tables-and-optimizer-statistics\/","url":"https:\/\/www.dbi-services.com\/blog\/postgresql-partitioned-tables-and-optimizer-statistics\/","name":"PostgreSQL: Partitioned tables and optimizer statistics - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"datePublished":"2024-09-25T11:11:05+00:00","dateModified":"2024-09-25T11:11:08+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/postgresql-partitioned-tables-and-optimizer-statistics\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/postgresql-partitioned-tables-and-optimizer-statistics\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/postgresql-partitioned-tables-and-optimizer-statistics\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"PostgreSQL: Partitioned tables and optimizer statistics"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66","name":"Daniel Westermann","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g","caption":"Daniel Westermann"},"description":"Daniel Westermann is Principal Consultant and Technology Leader Open Infrastructure at dbi services. He has more than 15 years of experience in management, engineering and optimization of databases and infrastructures, especially on Oracle and PostgreSQL. Since the beginning of his career, he has specialized in Oracle Technologies and is Oracle Certified Professional 12c and Oracle Certified Expert RAC\/GridInfra. Over time, Daniel has become increasingly interested in open source technologies, becoming \u201cTechnology Leader Open Infrastructure\u201d and PostgreSQL expert. \u00a0Based on community or EnterpriseDB tools, he develops and installs complex high available solutions with PostgreSQL. He is also a certified PostgreSQL Plus 9.0 Professional and a Postgres Advanced Server 9.4 Professional. He is a regular speaker at PostgreSQL conferences in Switzerland and Europe. Today Daniel is also supporting our customers on AWS services such as AWS RDS, database migrations into the cloud, EC2 and automated infrastructure management with AWS SSM (System Manager). He is a certified AWS Solutions Architect Professional. Prior to dbi services, Daniel was Management System Engineer at LC SYSTEMS-Engineering AG in Basel. Before that, he worked as Oracle Developper &amp;\u00a0Project Manager at Delta Energy Solutions AG in Basel (today Powel AG). Daniel holds a diploma in Business Informatics (DHBW, Germany). His branch-related experience mainly covers the pharma industry, the financial sector, energy, lottery and telecommunications.","sameAs":["https:\/\/x.com\/westermanndanie"],"url":"https:\/\/www.dbi-services.com\/blog\/author\/daniel-westermann\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/34811","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/29"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=34811"}],"version-history":[{"count":13,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/34811\/revisions"}],"predecessor-version":[{"id":34824,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/34811\/revisions\/34824"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=34811"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=34811"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=34811"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=34811"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}