{"id":12478,"date":"2019-05-31T18:02:08","date_gmt":"2019-05-31T16:02:08","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/postgresql-12-control-when-generic-plans-are-used\/"},"modified":"2019-05-31T18:02:08","modified_gmt":"2019-05-31T16:02:08","slug":"postgresql-12-control-when-generic-plans-are-used","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/postgresql-12-control-when-generic-plans-are-used\/","title":{"rendered":"PostgreSQL 12: Control when generic plans are used"},"content":{"rendered":"<p>When you are using <a href=\"https:\/\/www.dbi-services.com\/blog\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\/\" target=\"_blank\" rel=\"noopener noreferrer\">prepared statements<\/a> in PostgreSQL you might get a <a href=\"https:\/\/www.dbi-services.com\/blog\/what-are-custom-and-generic-plans-in-postgresql\/\" target=\"_blank\" rel=\"noopener noreferrer\">custom or a generic plan<\/a>. Custom plans come with overhead of re-planning while generic plans avoid re-planning of the statement. A soon as you get a generic plan that plan will be used for the lifetime of your session and there are situations when you do not want to see this as a generic plan might be more expensive than a custom plan. Starting with PostgreSQL 12 (<a href=\"https:\/\/www.postgresql.org\/about\/news\/1943\/\" target=\"_blank\" rel=\"noopener noreferrer\">which currently is in beta<\/a>) you have more control over this.<\/p>\n<p><!--more--><\/p>\n<p>Let use the same simple test case as in the previous post about custom and generic plans:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\npostgres=# select version();\n                                                  version                                                  \n-----------------------------------------------------------------------------------------------------------\n PostgreSQL 12devel on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.2.1 20180905 (Red Hat 8.2.1-3), 64-bit\n(1 row)\n\npostgres=# create table demo ( a int, b text );\nCREATE TABLE\npostgres=# insert into demo select i, 'aaa' from generate_series (1,100) i;\nINSERT 0 100\npostgres=# insert into demo select i, 'bbb' from generate_series (101,200) i;\nINSERT 0 100\npostgres=# insert into demo select i, 'ccc' from generate_series (201,300) i;\nINSERT 0 100\npostgres=# analyze demo;\nANALYZE\npostgres=# \n<\/pre>\n<p>When we prepare and then execute the blow statement 6 times we will see a generic plan:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1; highlight: [57]\">\npostgres=# prepare my_stmt as select * from demo where b = $1;\nPREPARE\npostgres=# explain (analyze) execute my_stmt ( 'aaa' );\n                                            QUERY PLAN                                            \n--------------------------------------------------------------------------------------------------\n Seq Scan on demo  (cost=0.00..5.75 rows=100 width=8) (actual time=0.027..0.107 rows=100 loops=1)\n   Filter: (b = 'aaa'::text)\n   Rows Removed by Filter: 200\n Planning Time: 0.431 ms\n Execution Time: 0.198 ms\n(5 rows)\n\npostgres=# explain (analyze) execute my_stmt ( 'aaa' );\n                                            QUERY PLAN                                            \n--------------------------------------------------------------------------------------------------\n Seq Scan on demo  (cost=0.00..5.75 rows=100 width=8) (actual time=0.032..0.113 rows=100 loops=1)\n   Filter: (b = 'aaa'::text)\n   Rows Removed by Filter: 200\n Planning Time: 0.196 ms\n Execution Time: 0.155 ms\n(5 rows)\n\npostgres=# explain (analyze) execute my_stmt ( 'aaa' );\n                                            QUERY PLAN                                            \n--------------------------------------------------------------------------------------------------\n Seq Scan on demo  (cost=0.00..5.75 rows=100 width=8) (actual time=0.032..0.113 rows=100 loops=1)\n   Filter: (b = 'aaa'::text)\n   Rows Removed by Filter: 200\n Planning Time: 0.168 ms\n Execution Time: 0.154 ms\n(5 rows)\n\npostgres=# explain (analyze) execute my_stmt ( 'aaa' );\n                                            QUERY PLAN                                            \n--------------------------------------------------------------------------------------------------\n Seq Scan on demo  (cost=0.00..5.75 rows=100 width=8) (actual time=0.041..0.135 rows=100 loops=1)\n   Filter: (b = 'aaa'::text)\n   Rows Removed by Filter: 200\n Planning Time: 0.238 ms\n Execution Time: 0.193 ms\n(5 rows)\n\npostgres=# explain (analyze) execute my_stmt ( 'aaa' );\n                                            QUERY PLAN                                            \n--------------------------------------------------------------------------------------------------\n Seq Scan on demo  (cost=0.00..5.75 rows=100 width=8) (actual time=0.031..0.112 rows=100 loops=1)\n   Filter: (b = 'aaa'::text)\n   Rows Removed by Filter: 200\n Planning Time: 0.169 ms\n Execution Time: 0.154 ms\n(5 rows)\n\npostgres=# explain (analyze) execute my_stmt ( 'aaa' );\n                                            QUERY PLAN                                            \n--------------------------------------------------------------------------------------------------\n Seq Scan on demo  (cost=0.00..5.75 rows=100 width=8) (actual time=0.033..0.120 rows=100 loops=1)\n   Filter: (b = $1)\n   Rows Removed by Filter: 200\n Planning Time: 0.163 ms\n Execution Time: 0.163 ms\n(5 rows)\n<\/pre>\n<p>PostgreSQL 12 will come with a new parameter to control that:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\npostgres=# show plan_cache_mode;\n plan_cache_mode \n-----------------\n auto\n(1 row)\npostgres=# select extra_desc from pg_settings where name = 'plan_cache_mode';\n                                                                            extra_desc                                                                             \n-------------------------------------------------------------------------------------------------------------------------------------------------------------------\n Prepared statements can have custom and generic plans, and the planner will attempt to choose which is better.  This can be set to override the default behavior.\n(1 row)\n<\/pre>\n<p>The default value is &#8220;auto&#8221; which means the same behavior is in previous versions of PostgreSQL. If you want to force custom plans you can set it to &#8220;force_custom_plan&#8221; or you can set it to &#8220;force_generic_plan&#8221; if you want to only see generic plans. Using the same example from above but setting the parameter to &#8220;force_custom_plan&#8221; we will not see a generic plan anymore:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\npostgres=# set plan_cache_mode = force_custom_plan;\nSET\npostgres=# explain (analyze) execute my_stmt ( 'aaa' );\n                                            QUERY PLAN                                            \n--------------------------------------------------------------------------------------------------\n Seq Scan on demo  (cost=0.00..5.75 rows=100 width=8) (actual time=0.034..0.127 rows=100 loops=1)\n   Filter: (b = 'aaa'::text)\n   Rows Removed by Filter: 200\n Planning Time: 0.209 ms\n Execution Time: 0.172 ms\n(5 rows)\n\npostgres=# explain (analyze) execute my_stmt ( 'aaa' );\n                                            QUERY PLAN                                            \n--------------------------------------------------------------------------------------------------\n Seq Scan on demo  (cost=0.00..5.75 rows=100 width=8) (actual time=0.152..0.236 rows=100 loops=1)\n   Filter: (b = 'aaa'::text)\n   Rows Removed by Filter: 200\n Planning Time: 0.170 ms\n Execution Time: 0.279 ms\n(5 rows)\n\npostgres=# explain (analyze) execute my_stmt ( 'aaa' );\n                                            QUERY PLAN                                            \n--------------------------------------------------------------------------------------------------\n Seq Scan on demo  (cost=0.00..5.75 rows=100 width=8) (actual time=0.031..0.112 rows=100 loops=1)\n   Filter: (b = 'aaa'::text)\n   Rows Removed by Filter: 200\n Planning Time: 0.170 ms\n Execution Time: 0.152 ms\n(5 rows)\n\npostgres=# explain (analyze) execute my_stmt ( 'aaa' );\n                                            QUERY PLAN                                            \n--------------------------------------------------------------------------------------------------\n Seq Scan on demo  (cost=0.00..5.75 rows=100 width=8) (actual time=0.029..0.122 rows=100 loops=1)\n   Filter: (b = 'aaa'::text)\n   Rows Removed by Filter: 200\n Planning Time: 0.206 ms\n Execution Time: 0.162 ms\n(5 rows)\n\npostgres=# explain (analyze) execute my_stmt ( 'aaa' );\n                                            QUERY PLAN                                            \n--------------------------------------------------------------------------------------------------\n Seq Scan on demo  (cost=0.00..5.75 rows=100 width=8) (actual time=0.038..0.133 rows=100 loops=1)\n   Filter: (b = 'aaa'::text)\n   Rows Removed by Filter: 200\n Planning Time: 0.200 ms\n Execution Time: 0.244 ms\n(5 rows)\n\npostgres=# explain (analyze) execute my_stmt ( 'aaa' );\n                                            QUERY PLAN                                            \n--------------------------------------------------------------------------------------------------\n Seq Scan on demo  (cost=0.00..5.75 rows=100 width=8) (actual time=0.032..0.114 rows=100 loops=1)\n   Filter: (b = 'aaa'::text)\n   Rows Removed by Filter: 200\n Planning Time: 0.169 ms\n Execution Time: 0.155 ms\n(5 rows)\n\npostgres=# explain (analyze) execute my_stmt ( 'aaa' );\n                                            QUERY PLAN                                            \n--------------------------------------------------------------------------------------------------\n Seq Scan on demo  (cost=0.00..5.75 rows=100 width=8) (actual time=0.034..0.117 rows=100 loops=1)\n   Filter: (b = 'aaa'::text)\n   Rows Removed by Filter: 200\n Planning Time: 0.301 ms\n Execution Time: 0.162 ms\n(5 rows)\n<\/pre>\n<p>Nice addition that can help when you have generic plans that actually perform worse than custom plans.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When you are using prepared statements in PostgreSQL you might get a custom or a generic plan. Custom plans come with overhead of re-planning while generic plans avoid re-planning of the statement. A soon as you get a generic plan that plan will be used for the lifetime of your session and there are situations [&hellip;]<\/p>\n","protected":false},"author":29,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[229],"tags":[77],"type_dbi":[],"class_list":["post-12478","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 12: Control when generic plans are used - 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-12-control-when-generic-plans-are-used\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"PostgreSQL 12: Control when generic plans are used\" \/>\n<meta property=\"og:description\" content=\"When you are using prepared statements in PostgreSQL you might get a custom or a generic plan. Custom plans come with overhead of re-planning while generic plans avoid re-planning of the statement. A soon as you get a generic plan that plan will be used for the lifetime of your session and there are situations [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/postgresql-12-control-when-generic-plans-are-used\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2019-05-31T16:02: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=\"4 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-12-control-when-generic-plans-are-used\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/postgresql-12-control-when-generic-plans-are-used\/\"},\"author\":{\"name\":\"Daniel Westermann\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66\"},\"headline\":\"PostgreSQL 12: Control when generic plans are used\",\"datePublished\":\"2019-05-31T16:02:08+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/postgresql-12-control-when-generic-plans-are-used\/\"},\"wordCount\":226,\"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-12-control-when-generic-plans-are-used\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/postgresql-12-control-when-generic-plans-are-used\/\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/postgresql-12-control-when-generic-plans-are-used\/\",\"name\":\"PostgreSQL 12: Control when generic plans are used - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\"},\"datePublished\":\"2019-05-31T16:02:08+00:00\",\"author\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/postgresql-12-control-when-generic-plans-are-used\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/postgresql-12-control-when-generic-plans-are-used\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/postgresql-12-control-when-generic-plans-are-used\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/www.dbi-services.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"PostgreSQL 12: Control when generic plans are used\"}]},{\"@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 12: Control when generic plans are used - 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-12-control-when-generic-plans-are-used\/","og_locale":"en_US","og_type":"article","og_title":"PostgreSQL 12: Control when generic plans are used","og_description":"When you are using prepared statements in PostgreSQL you might get a custom or a generic plan. Custom plans come with overhead of re-planning while generic plans avoid re-planning of the statement. A soon as you get a generic plan that plan will be used for the lifetime of your session and there are situations [&hellip;]","og_url":"https:\/\/www.dbi-services.com\/blog\/postgresql-12-control-when-generic-plans-are-used\/","og_site_name":"dbi Blog","article_published_time":"2019-05-31T16:02:08+00:00","author":"Daniel Westermann","twitter_card":"summary_large_image","twitter_creator":"@westermanndanie","twitter_misc":{"Written by":"Daniel Westermann","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/postgresql-12-control-when-generic-plans-are-used\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/postgresql-12-control-when-generic-plans-are-used\/"},"author":{"name":"Daniel Westermann","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66"},"headline":"PostgreSQL 12: Control when generic plans are used","datePublished":"2019-05-31T16:02:08+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/postgresql-12-control-when-generic-plans-are-used\/"},"wordCount":226,"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-12-control-when-generic-plans-are-used\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/postgresql-12-control-when-generic-plans-are-used\/","url":"https:\/\/www.dbi-services.com\/blog\/postgresql-12-control-when-generic-plans-are-used\/","name":"PostgreSQL 12: Control when generic plans are used - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"datePublished":"2019-05-31T16:02:08+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/postgresql-12-control-when-generic-plans-are-used\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/postgresql-12-control-when-generic-plans-are-used\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/postgresql-12-control-when-generic-plans-are-used\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"PostgreSQL 12: Control when generic plans are used"}]},{"@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\/12478","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=12478"}],"version-history":[{"count":0,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/12478\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=12478"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=12478"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=12478"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=12478"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}