{"id":11043,"date":"2018-03-26T09:13:32","date_gmt":"2018-03-26T07:13:32","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\/"},"modified":"2018-03-26T09:13:32","modified_gmt":"2018-03-26T07:13:32","slug":"when-you-execute-the-same-statement-thousands-of-times-prepare-it","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\/","title":{"rendered":"When you execute the same statement thousands of times -&gt; prepare it"},"content":{"rendered":"<p>Every time you send a SQL statement to PostgreSQL it must be parsed. Parsing is fast, yes, but parsing the same statement a thousand times can quickly sum up to quite some time the database could spend for something else. To avoid that PostgreSQL comes with the <a href=\"https:\/\/www.postgresql.org\/docs\/current\/static\/sql-prepare.html\" target=\"_blank\" rel=\"noopener\">prepare<\/a> statement. Using that you can avoid parsing of statements and only planning and executing will happen. Lets see how that works.<\/p>\n<p><!--more--><\/p>\n<p>To generate some sample data I used <a href=\"https:\/\/www.postgresql.org\/docs\/current\/static\/pgbench.html\" target=\"_blank\" rel=\"noopener\">pgbench<\/a> with a scale factor of 100 which gives me 10&#8217;000&#8217;000 rows in the pgbench_accounts table:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\npostgres@pgbox:\/home\/postgres\/ [PGDEV] pgbench -i -s 100 bench\npostgres@pgbox:\/home\/postgres\/ [PGDEV] psql bench\n\npsql (11devel)\nType \"help\" for help.\n\nbench=# select count(*) from pgbench_accounts;\n  count   \n----------\n 10000000\n(1 row)\n\nbench=# d pgbench_accounts\n              Table \"public.pgbench_accounts\"\n  Column  |     Type      | Collation | Nullable | Default \n----------+---------------+-----------+----------+---------\n aid      | integer       |           | not null | \n bid      | integer       |           |          | \n abalance | integer       |           |          | \n filler   | character(84) |           |          | \nIndexes:\n    \"pgbench_accounts_pkey\" PRIMARY KEY, btree (aid)\n<\/pre>\n<p>Lets assume we have the following simple query:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\nbench=# select count(*) from pgbench_accounts where aid = 11111;\n count \n-------\n     1\n(1 row)\n<\/pre>\n<p>As said at the beginning of this post PostgreSQL will need to parse that statement. Using <a href=\"https:\/\/www.postgresql.org\/docs\/current\/static\/using-explain.html\" target=\"_blank\" rel=\"noopener\">explain<\/a> with the right options you are able to see how much time was spend on planning:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1; highlight: [10]\">\nbench=# explain (analyze,buffers) select count(*) from pgbench_accounts where aid = 11111;\n                                                                    QUERY PLAN                                                                     \n---------------------------------------------------------------------------------------------------------------------------------------------------\n Aggregate  (cost=4.46..4.46 rows=1 width=8) (actual time=0.060..0.063 rows=1 loops=1)\n   Buffers: shared hit=4\n   -&gt;  Index Only Scan using pgbench_accounts_pkey on pgbench_accounts  (cost=0.43..4.45 rows=1 width=0) (actual time=0.034..0.039 rows=1 loops=1)\n         Index Cond: (aid = 11111)\n         Heap Fetches: 0\n         Buffers: shared hit=4\n Planning Time: 0.150 ms\n Execution Time: 0.133 ms\n(8 rows)\n<\/pre>\n<p>Planning this statement takes more time then executing it. Now assume you want to execute that very same statement one thousand times:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\nbench=# t\nbench=# select 'select count(*) from pgbench_accounts where aid = 11111;' from generate_series(1,1000) i; g test.sql\nbench=# ! cat test.sql | head\n select count(*) from pgbench_accounts where aid = 11111;\n select count(*) from pgbench_accounts where aid = 11111;\n select count(*) from pgbench_accounts where aid = 11111;\n select count(*) from pgbench_accounts where aid = 11111;\n select count(*) from pgbench_accounts where aid = 11111;\n select count(*) from pgbench_accounts where aid = 11111;\n select count(*) from pgbench_accounts where aid = 11111;\n select count(*) from pgbench_accounts where aid = 11111;\n select count(*) from pgbench_accounts where aid = 11111;\n select count(*) from pgbench_accounts where aid = 11111;\n...\n<\/pre>\n<p>When we execute that we force PostgreSQL to parse all of those 1000 statements:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\nbench=# timing\nTiming is on.\nbench=# ! time psql -f test.sql bench\n\nreal\t0m0.148s\nuser\t0m0.031s\nsys\t0m0.015s\n<\/pre>\n<p>What you can do to avoid that is to prepare the statement:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\nbench=# prepare tt as select count(*) from pgbench_accounts where aid = 11111;\nPREPARE\n<\/pre>\n<p>Once it is prepared you can execute it:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\nbench=# execute tt;\n count \n-------\n     1\n(1 row)\n<\/pre>\n<p>&#8230; and you can also explain it:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\nbench=# explain(analyze,buffers) execute tt;\n                                                                    QUERY PLAN                                                                     \n---------------------------------------------------------------------------------------------------------------------------------------------------\n Aggregate  (cost=4.46..4.46 rows=1 width=8) (actual time=0.066..0.069 rows=1 loops=1)\n   Buffers: shared hit=4\n   -&gt;  Index Only Scan using pgbench_accounts_pkey on pgbench_accounts  (cost=0.43..4.45 rows=1 width=0) (actual time=0.037..0.043 rows=1 loops=1)\n         Index Cond: (aid = 11111)\n         Heap Fetches: 0\n         Buffers: shared hit=4\n Planning Time: 0.021 ms\n Execution Time: 0.269 ms\n(8 rows)\n<\/pre>\n<p>You&#8217;ll notice that the planning time went down quite a lot compared to the not prepared statement:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\nbench=# explain (analyze,buffers) select count(*) from pgbench_accounts where aid = 11111;\n                                                                    QUERY PLAN                                                                     \n---------------------------------------------------------------------------------------------------------------------------------------------------\n Aggregate  (cost=4.46..4.46 rows=1 width=8) (actual time=0.167..0.172 rows=1 loops=1)\n   Buffers: shared hit=4\n   -&gt;  Index Only Scan using pgbench_accounts_pkey on pgbench_accounts  (cost=0.43..4.45 rows=1 width=0) (actual time=0.030..0.037 rows=1 loops=1)\n         Index Cond: (aid = 11111)\n         Heap Fetches: 0\n         Buffers: shared hit=4\n Planning Time: 0.167 ms\n Execution Time: 0.248 ms\n(8 rows)\n<\/pre>\n<p>When you do that one thousand times now:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\nbench=# t\nbench=# select 'execute tt;' from generate_series(1,1000) i; g test.sql\nbench=# ! sed -i '1s\/^\/prepare tt as select count(*) from pgbench_accounts where aid = 11111;\/' test.sql\nbench=# ! time psql -f test.sql bench\n\nreal\t0m0.095s\nuser\t0m0.031s\nsys\t0m0.010s\n<\/pre>\n<p>&#8230; execution time will come down. It is not much in that simple case but this is due to the simple statement. Btw: As prepared statements only life for the time of the session the sed command adds the prepare statement to the top of file, and preparing takes time as well. Without that execution time would be even less.<\/p>\n<p>When your values change in the where clause you can do it like this:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\nbench=# prepare tt as select count(*) from pgbench_accounts where aid = $1;\nPREPARE\nTime: 0.571 ms\nbench=# execute tt (123);\n     1\n<\/pre>\n<p>For completeness: When you want to get rid of a prepared statement without losing your session there is <a href=\"https:\/\/www.postgresql.org\/docs\/10\/static\/sql-deallocate.html\" target=\"_blank\" rel=\"noopener\">deallocate<\/a>:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\nbench=# deallocate tt;\nDEALLOCATE\nTime: 0.623 ms\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Every time you send a SQL statement to PostgreSQL it must be parsed. Parsing is fast, yes, but parsing the same statement a thousand times can quickly sum up to quite some time the database could spend for something else. To avoid that PostgreSQL comes with the prepare statement. Using that you can avoid parsing [&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-11043","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.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>When you execute the same statement thousands of times -&gt; prepare it - 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\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"When you execute the same statement thousands of times -&gt; prepare it\" \/>\n<meta property=\"og:description\" content=\"Every time you send a SQL statement to PostgreSQL it must be parsed. Parsing is fast, yes, but parsing the same statement a thousand times can quickly sum up to quite some time the database could spend for something else. To avoid that PostgreSQL comes with the prepare statement. Using that you can avoid parsing [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2018-03-26T07:13:32+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\\\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\\\/\"},\"author\":{\"name\":\"Daniel Westermann\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/8d08e9bd996a89bd75c0286cbabf3c66\"},\"headline\":\"When you execute the same statement thousands of times -&gt; prepare it\",\"datePublished\":\"2018-03-26T07:13:32+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\\\/\"},\"wordCount\":324,\"commentCount\":0,\"keywords\":[\"PostgreSQL\"],\"articleSection\":[\"Database Administration &amp; Monitoring\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\\\/\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\\\/\",\"name\":\"When you execute the same statement thousands of times -&gt; prepare it - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#website\"},\"datePublished\":\"2018-03-26T07:13:32+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/8d08e9bd996a89bd75c0286cbabf3c66\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"When you execute the same statement thousands of times -&gt; prepare it\"}]},{\"@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":"When you execute the same statement thousands of times -&gt; prepare it - 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\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\/","og_locale":"en_US","og_type":"article","og_title":"When you execute the same statement thousands of times -&gt; prepare it","og_description":"Every time you send a SQL statement to PostgreSQL it must be parsed. Parsing is fast, yes, but parsing the same statement a thousand times can quickly sum up to quite some time the database could spend for something else. To avoid that PostgreSQL comes with the prepare statement. Using that you can avoid parsing [&hellip;]","og_url":"https:\/\/www.dbi-services.com\/blog\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\/","og_site_name":"dbi Blog","article_published_time":"2018-03-26T07:13:32+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\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\/"},"author":{"name":"Daniel Westermann","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66"},"headline":"When you execute the same statement thousands of times -&gt; prepare it","datePublished":"2018-03-26T07:13:32+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\/"},"wordCount":324,"commentCount":0,"keywords":["PostgreSQL"],"articleSection":["Database Administration &amp; Monitoring"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\/","url":"https:\/\/www.dbi-services.com\/blog\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\/","name":"When you execute the same statement thousands of times -&gt; prepare it - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"datePublished":"2018-03-26T07:13:32+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/when-you-execute-the-same-statement-thousands-of-times-prepare-it\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"When you execute the same statement thousands of times -&gt; prepare it"}]},{"@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\/11043","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=11043"}],"version-history":[{"count":0,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/11043\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=11043"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=11043"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=11043"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=11043"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}