{"id":9026,"date":"2016-10-14T05:11:10","date_gmt":"2016-10-14T03:11:10","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/how-to-destroy-your-performance-plsql-vs-sql\/"},"modified":"2016-10-14T05:11:10","modified_gmt":"2016-10-14T03:11:10","slug":"how-to-destroy-your-performance-plsql-vs-sql","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/how-to-destroy-your-performance-plsql-vs-sql\/","title":{"rendered":"How to destroy your performance: PL\/SQL vs SQL"},"content":{"rendered":"<p>Disclaimer: This is in no way a recommendation to avoid PL\/SQL. This post just describes a case I faced at a customer with a specific implementation in PL\/SQL the customer (and me) believed is the most efficient way of doing it in PL\/SQL. This was a very good example for myself to remind me to check the documentation and to verify if what I believed a feature does is really what the feature is actually doing. When I was doing PL\/SQL full time in one my of previous jobs I used the feature heavily without really thinking on what happened in the background. Always keep learning &#8230;<\/p>\n<p><!--more--><\/p>\n<p>Lets start by building the test case. The issue was on 12.1.0.2 on Linux but I think this will be reproducible on any release (although, never be sure \ud83d\ude42 ).  <\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\nSQL&gt; create table t1 as select * from dba_objects;\nSQL&gt; insert into t1 select * from t1;\nSQL&gt; \/\nSQL&gt; \/\nSQL&gt; \/\nSQL&gt; \/\nSQL&gt; \/\nSQL commit;\nSQL&gt; select count(*) from t1;\n\n  COUNT(*)\n----------\n   5565632\n\nSQL&gt; create table t2 as select object_id from t1 where mod(object_id,33)=0;\nSQL&gt; select count(*) from t2;\n\n  COUNT(*)\n----------\n    168896\n<\/pre>\n<p>This are my two tables used for the test: t1 contains around 5,5 millions rows and there is t2 which contains 168896 rows. Coming to the issue: There is a procedure which does this:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\ncreate or replace procedure test_update\nis\n  cursor c1 is select object_id from t2;\n  type tab is table of t2.object_id%type index by pls_integer;\n  ltab tab;\nbegin\n  open c1;\n  fetch c1 bulk collect into ltab;\n  close c1;\n  forall indx in 1..ltab.count\n    update t1 set owner = 'AAA' where object_id = ltab(indx);\nend test_update;\n\/\n<\/pre>\n<p>The procedure uses &#8220;bulk collect&#8221; and &#8220;forall&#8221; to fetch the keys from t2 in a first step and then uses these keys to update t1 in a second step. Seemed pretty well done: Not a loop over each single row, compare with the list and then do the update when there is a match. I really couldn&#8217;t see an issue here. But when you execute this procedure you&#8217;ll wait for ages (at least if you are in VM running on a notebook and not on super fast hardware).<\/p>\n<p>The situation at the customer was that I was told that the update, when executed as plain SQL in sqlplus, takes less than a second. And really, when you execute this on the test case from above:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\nSQL&gt; update t1 set owner = 'AAA' where object_id in ( select object_id from t2 );\n\n168896 rows updated.\n\nElapsed: 00:00:05.30\nSQL&gt; rollback;\n\nRollback complete.\n\nElapsed: 00:00:02.44\nSQL&gt; update t1 set owner = 'AAA' where object_id in ( select object_id from t2 );\n\n168896 rows updated.\n\nElapsed: 00:00:06.34\nSQL&gt; rollback;\n\nRollback complete.\n\nElapsed: 00:00:02.70\nSQL&gt;\n<\/pre>\n<p>It is quite fast (between 5 and 6 seconds on my environment). So why is the PL\/SQL version so much slower? Aren&#8217;t &#8220;bulk collect&#8221; and &#8220;forall&#8221; the right methods to boost performance? Lets take a look at the execution plan for the plain SQL version:<\/p>\n<pre class=\"brush: text; gutter: true; first-line: 1\">\n----------------------------------------------------------------------------------------------------------------------------------------------------------------\n| Id  | Operation             | Name     | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |    A-Time     | Buffers | Reads  |  OMem |  1Mem |  O\/1\/M|\n----------------------------------------------------------------------------------------------------------------------------------------------------------------\n|   0 | UPDATE STATEMENT      |          |      1 |       |       | 24303 (100)|          |       0 |00:00:04.52    |     259K|   9325 |       |       |       |\n|   1 |  UPDATE               | T1       |      1 |       |       |            |          |       0 |00:00:04.52    |     259K|   9325 |       |       |       |\n|*  2 |   HASH JOIN           |          |      1 |    48 |  4416 | 24303   (1)| 00:00:01 |     168K|00:00:01.76    |   86719 |   9325 |  2293K|  2293K|  1\/0\/0|\n|   3 |    VIEW               | VW_NSO_1 |      1 |   161K|  2044K|    72   (2)| 00:00:01 |    2639 |00:00:00.05    |     261 |     78 |       |       |       |\n|   4 |     SORT UNIQUE       |          |      1 |     1 |  2044K|            |          |    2639 |00:00:00.04    |     261 |     78 |   142K|   142K|  1\/0\/0|\n|   5 |      TABLE ACCESS FULL| T2       |      1 |   161K|  2044K|    72   (2)| 00:00:01 |     168K|00:00:00.01    |     261 |     78 |       |       |       |\n|   6 |    TABLE ACCESS FULL  | T1       |      1 |  5700K|   429M| 23453   (1)| 00:00:01 |    5566K|00:00:05.88    |   86458 |   9247 |       |       |       |\n----------------------------------------------------------------------------------------------------------------------------------------------------------------\n<\/pre>\n<p>It is doing a hash join as expected. What about the PL\/SQL version? It is doing this:<\/p>\n<pre class=\"brush: text; gutter: true; first-line: 1\">\nPLAN_TABLE_OUTPUT\n----------------------------------------------------------------------------\nSQL_ID  4hh65t1u4basp, child number 0\n-------------------------------------\nUPDATE T1 SET OWNER = 'AAA' WHERE OBJECT_ID = :B1\n\nPlan hash value: 2927627013\n\n---------------------------------------------------------------------------\n| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |\n---------------------------------------------------------------------------\n|   0 | UPDATE STATEMENT   |      |       |       | 23459 (100)|          |\n|   1 |  UPDATE            | T1   |       |       |            |          |\n|*  2 |   TABLE ACCESS FULL| T1   |   951 | 75129 | 23459   (1)| 00:00:01 |\n---------------------------------------------------------------------------\n<\/pre>\n<p>Uh! Why that? This is what I wasn&#8217;t aware of. I always thought when you use &#8220;forall&#8221; to send PL\/SQL&#8217;s SQL to the SQL engine Oracle would rewrite the statement to expand the list in the where clause or do other optimizations. But this does not happen. The only optimization that takes place when you use &#8220;forall&#8221; is that the statements are send in batches to the SQL engine rather then sending each statement after another. What happens here is that you execute 168896 full table scans because the same statement (with a another bind variable value) is executed 168896 times. Can&#8217;t be really fast compared to the SQL version.<\/p>\n<p>Of course you could rewrite the procedure to do the same as the SQL but this is not the point here. The point is: When you think what you have implemented in PL\/SQL is the same as what you compare to when you run it SQL: Better think twice and even better read the f* manuals, even when you think you are sure what a feature really does \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Disclaimer: This is in no way a recommendation to avoid PL\/SQL. This post just describes a case I faced at a customer with a specific implementation in PL\/SQL the customer (and me) believed is the most efficient way of doing it in PL\/SQL. This was a very good example for myself to remind me to [&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":[96,24,98],"type_dbi":[],"class_list":["post-9026","post","type-post","status-publish","format-standard","hentry","category-database-administration-monitoring","tag-oracle","tag-pl-sql","tag-sql"],"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>How to destroy your performance: PL\/SQL vs SQL - 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\/how-to-destroy-your-performance-plsql-vs-sql\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to destroy your performance: PL\/SQL vs SQL\" \/>\n<meta property=\"og:description\" content=\"Disclaimer: This is in no way a recommendation to avoid PL\/SQL. This post just describes a case I faced at a customer with a specific implementation in PL\/SQL the customer (and me) believed is the most efficient way of doing it in PL\/SQL. This was a very good example for myself to remind me to [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/how-to-destroy-your-performance-plsql-vs-sql\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2016-10-14T03:11:10+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\/how-to-destroy-your-performance-plsql-vs-sql\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/how-to-destroy-your-performance-plsql-vs-sql\/\"},\"author\":{\"name\":\"Daniel Westermann\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66\"},\"headline\":\"How to destroy your performance: PL\/SQL vs SQL\",\"datePublished\":\"2016-10-14T03:11:10+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/how-to-destroy-your-performance-plsql-vs-sql\/\"},\"wordCount\":549,\"commentCount\":0,\"keywords\":[\"Oracle\",\"PL\/SQL\",\"SQL\"],\"articleSection\":[\"Database Administration &amp; Monitoring\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/how-to-destroy-your-performance-plsql-vs-sql\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/how-to-destroy-your-performance-plsql-vs-sql\/\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/how-to-destroy-your-performance-plsql-vs-sql\/\",\"name\":\"How to destroy your performance: PL\/SQL vs SQL - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\"},\"datePublished\":\"2016-10-14T03:11:10+00:00\",\"author\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/how-to-destroy-your-performance-plsql-vs-sql\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/how-to-destroy-your-performance-plsql-vs-sql\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/how-to-destroy-your-performance-plsql-vs-sql\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/www.dbi-services.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to destroy your performance: PL\/SQL vs SQL\"}]},{\"@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":"How to destroy your performance: PL\/SQL vs SQL - 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\/how-to-destroy-your-performance-plsql-vs-sql\/","og_locale":"en_US","og_type":"article","og_title":"How to destroy your performance: PL\/SQL vs SQL","og_description":"Disclaimer: This is in no way a recommendation to avoid PL\/SQL. This post just describes a case I faced at a customer with a specific implementation in PL\/SQL the customer (and me) believed is the most efficient way of doing it in PL\/SQL. This was a very good example for myself to remind me to [&hellip;]","og_url":"https:\/\/www.dbi-services.com\/blog\/how-to-destroy-your-performance-plsql-vs-sql\/","og_site_name":"dbi Blog","article_published_time":"2016-10-14T03:11:10+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\/how-to-destroy-your-performance-plsql-vs-sql\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/how-to-destroy-your-performance-plsql-vs-sql\/"},"author":{"name":"Daniel Westermann","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66"},"headline":"How to destroy your performance: PL\/SQL vs SQL","datePublished":"2016-10-14T03:11:10+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/how-to-destroy-your-performance-plsql-vs-sql\/"},"wordCount":549,"commentCount":0,"keywords":["Oracle","PL\/SQL","SQL"],"articleSection":["Database Administration &amp; Monitoring"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/how-to-destroy-your-performance-plsql-vs-sql\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/how-to-destroy-your-performance-plsql-vs-sql\/","url":"https:\/\/www.dbi-services.com\/blog\/how-to-destroy-your-performance-plsql-vs-sql\/","name":"How to destroy your performance: PL\/SQL vs SQL - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"datePublished":"2016-10-14T03:11:10+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/how-to-destroy-your-performance-plsql-vs-sql\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/how-to-destroy-your-performance-plsql-vs-sql\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/how-to-destroy-your-performance-plsql-vs-sql\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"How to destroy your performance: PL\/SQL vs SQL"}]},{"@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\/9026","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=9026"}],"version-history":[{"count":0,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/9026\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=9026"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=9026"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=9026"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=9026"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}