{"id":10449,"date":"2017-08-24T20:03:34","date_gmt":"2017-08-24T18:03:34","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-x-update\/"},"modified":"2017-08-24T20:03:34","modified_gmt":"2017-08-24T18:03:34","slug":"postgres-vs-oracle-access-paths-x-update","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-x-update\/","title":{"rendered":"Postgres vs. Oracle access paths X &#8211; Update"},"content":{"rendered":"<h2>By Franck Pachot<\/h2>\n<p>.<br \/>\nIn the <a href=\"https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-ix\/\" target=\"_blank\" rel=\"noopener noreferrer\">previous post<\/a> we have seen the cheapest way to get one row, reading only one block from its physical location. But that&#8217;s the optimal case where the row has not moved. I&#8217;ll (nearly) conclude this series about access path with an update.<br \/>\n<!--more--><\/p>\n<h3>ROWID in Oracle<\/h3>\n<p>Here is the ROWID of one row in Oracle:<\/p>\n<pre><code>\nselect rowid from demo1  where n=1000;\nROWID\n------------------\nAAAR4WAAMAAAAEaAAF\n<\/code><\/pre>\n<p>There&#8217;s enough information here to get directly to the block with file_name and offset:<\/p>\n<pre><code>select file_name,dbms_rowid.rowid_block_number('AAAR4WAAMAAAAEaAAF')*block_size offset\n   from dba_data_files join dba_tablespaces using(tablespace_name)\n   where file_id=dbms_rowid.rowid_to_absolute_fno('AAAR4WAAMAAAAEaAAF','DEMO','DEMO1');\n&nbsp;\nFILE_NAME                                    OFFSET\n---------------------------------------- ----------\n\/u01\/oradata\/CDB1A\/PDB\/users01.dbf          2310144\n<\/code><\/pre>\n<p>The ROWID also contains the index of the row within the block&#8217;s row directory:<\/p>\n<pre><code>\nselect dbms_rowid.rowid_row_number('AAAR4WAAMAAAAEaAAF') from dual;\n&nbsp;\nDBMS_ROWID.ROWID_ROW_NUMBER('AAAR4WAAMAAAAEAAAF')\n-------------------------------------------------\n                                                5\n<\/code><\/pre>\n<h3>TID in Postgres<\/h3>\n<p>And the TID of similar row in Postgres:<\/p>\n<pre><code>\nselect ctid from demo1  where n=1000;\n  ctid\n---------\n (142,6)\n<\/code><\/pre>\n<p>The file is known from the table, as there is only one file per table:<\/p>\n<pre><code>\nshow data_directory;\n       data_directory\n----------------------------\n \/usr\/share\/postgresql\/data\n&nbsp;\nselect pg_relation_filepath('demo1');\n pg_relation_filepath\n----------------------\n base\/16437\/125852\n<\/code><\/pre>\n<p>The blocksize is common for the whole database:<\/p>\n<pre><code>\nshow block_size;\n block_size\n------------\n 8192\n<\/code><\/pre>\n<p>Then the block is at offset 142+8192=8334.<br \/>\nWithin the block, the row is at index 6.<\/p>\n<h3>SELECT<\/h3>\n<p>We have seen in the previous post that we can select using the ROWID\/TID and Oracle and Postgres behave the same: only one block to read, cost estimation based on one random read:<\/p>\n<pre><code>\nPLAN_TABLE_OUTPUT\n------------------------------------------------------------------------------------------------------------------------------------------------------\nSQL_ID  8mj3ms08x0sfh, child number 0\n-------------------------------------\nselect \/*+  *\/  a from demo1  where rowid='AAAR4WAAMAAAAEaAAF'\n-----------------------------------------------------------------------------------------------------------\n| Id  | Operation                  | Name  | Starts | E-Rows | Cost (%CPU)| A-Rows |   A-Time   | Buffers |\n-----------------------------------------------------------------------------------------------------------\n|   0 | SELECT STATEMENT           |       |      1 |        |     1 (100)|      1 |00:00:00.01 |       1 |\n|   1 |  TABLE ACCESS BY USER ROWID| DEMO1 |      1 |      1 |     1   (0)|      1 |00:00:00.01 |       1 |\n-----------------------------------------------------------------------------------------------------------\nColumn Projection Information (identified by operation id):\n-----------------------------------------------------------\n   1 - \"A\"[NUMBER,22]\n<\/code><\/pre>\n<p>Different units but same signification: cost=1 for Oracle is for random reads, cost=1 for Postgres is for sequential reads and random reads are estimated to cost=4:<\/p>\n<pre><code>\nexplain (analyze,verbose,costs,buffers) select  a from demo1  where ctid='(142,6)' ;\n                                              QUERY PLAN\n------------------------------------------------------------------------------------------------------\n Tid Scan on public.demo1  (cost=0.00..4.01 rows=1 width=4) (actual time=0.007..0.007 rows=1 loops=1)\n   Output: a\n   TID Cond: (demo1.ctid = '(142,6)'::tid)\n   Buffers: shared hit=1\n Planning time: 0.358 ms\n Execution time: 0.016 ms\n<\/code><\/pre>\n<h3>Oracle UPDATE<\/h3>\n<p>Now I&#8217;m updating this row, changing the column X which contains 1000 &#8216;x&#8217; characters to 1000 &#8216;y&#8217; characters:<\/p>\n<pre><code>\nPLAN_TABLE_OUTPUT\n------------------------------------------------------------------------------------------------------------------------------------------------------\nSQL_ID  gpqv4k6m1q20y, child number 0\n-------------------------------------\nupdate \/*+  *\/  demo1 set x=lpad('y',1000,'y') where rowid='AAAR4WAAMAAAAEaAAF'\n------------------------------------------------------------------------------------------------------------\n| Id  | Operation                   | Name  | Starts | E-Rows | Cost (%CPU)| A-Rows |   A-Time   | Buffers |\n------------------------------------------------------------------------------------------------------------\n|   0 | UPDATE STATEMENT            |       |      1 |        |     1 (100)|      0 |00:00:00.01 |       4 |\n|   1 |  UPDATE                     | DEMO1 |      1 |        |            |      0 |00:00:00.01 |       4 |\n|   2 |   TABLE ACCESS BY USER ROWID| DEMO1 |      1 |      1 |     1   (0)|      1 |00:00:00.01 |       1 |\n------------------------------------------------------------------------------------------------------------\nColumn Projection Information (identified by operation id):\n-----------------------------------------------------------\n   2 - (upd=2) ROWID[ROWID,10], \"X\"[VARCHAR2,1000]\n<\/code><\/pre>\n<p>In addition to the access to the block (1 buffer) the update had to read 3 additional buffers. There are no indexes on this updated column and then Oracle has no additional maintenance to do. One buffer is the table block to update (the TABLE ACCESS BY USER ROWID was a consistent get, the update needs the current version of the block). <\/p>\n<p>Additional buffers are from the UNDO tablespace for MVCC (Multi Version Concurrency Control). It is the first modification in my transaction and then has to update the transaction table and undo segment, which is why we see 2 additional buffers. Another update within the same transaction reads only two buffers in total:<\/p>\n<pre><code>\nPLAN_TABLE_OUTPUT\n------------------------------------------------------------------------------------------------------------------------------------------------------\nSQL_ID  gpqv4k6m1q20y, child number 0\n-------------------------------------\nupdate \/*+  *\/  demo1 set x=lpad('z',1000,'z') where rowid='AAAR4WAAMAAAAEaAAF'\n------------------------------------------------------------------------------------------------------------\n| Id  | Operation                   | Name  | Starts | E-Rows | Cost (%CPU)| A-Rows |   A-Time   | Buffers |\n------------------------------------------------------------------------------------------------------------\n|   0 | UPDATE STATEMENT            |       |      1 |        |     1 (100)|      0 |00:00:00.01 |       2 |\n|   1 |  UPDATE                     | DEMO1 |      1 |        |            |      0 |00:00:00.01 |       2 |\n|   2 |   TABLE ACCESS BY USER ROWID| DEMO1 |      1 |      1 |     1   (0)|      1 |00:00:00.01 |       1 |\n------------------------------------------------------------------------------------------------------------\nColumn Projection Information (identified by operation id):\n-----------------------------------------------------------\n   2 - (upd=2) ROWID[ROWID,10], \"X\"[VARCHAR2,1000]\n<\/code><\/pre>\n<p>Only the table blocks are read: one consistent read as of the beginning of the query (or the transaction if in serializable isolation level) and one for the current block. Oracle has an optimization called In-Memory UNDO to avoid frequent access undo blocks.<\/p>\n<p>There are no further re-visits needed. Oracle may choose to come back at commit if it can be done quickly (few blocks still in buffer cache) but that&#8217;s not required. The block can stay like this for years without the need to read it again for cleanup. If another session has to read it, then cleanup may be done by this session.<\/p>\n<h3>Postgres UPDATE<\/h3>\n<p>Here is the same update in Postgres:<\/p>\n<pre><code>\nexplain (analyze,verbose,costs,buffers) update  demo1 set x=lpad('y',1000,'y') where ctid='(142,6)' ;\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  QUERY PLAN                                                                                                                                                                                                                                                                                                                                                                                                                                          \n------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n Update on public.demo1  (cost=0.00..4.01 rows=1 width=46) (actual time=0.214..0.214 rows=0 loops=1)\n   Buffers: shared hit=6 dirtied=3\n   -&gt;  Tid Scan on public.demo1  (cost=0.00..4.01 rows=1 width=46) (actual time=0.009..0.009 rows=1 loops=1)\n         Output: n, a, 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'::text, ctid\n         TID Cond: (demo1.ctid = '(142,6)'::tid)\n         Buffers: shared hit=1\n Planning time: 0.405 ms\n Execution time: 0.232 ms\n<\/code><\/pre>\n<p>The Tid Scan is the same as for the select. Then the update has read 5 blocks and modified 3 of them. The update in Postgres is processed as a delete+insert. Here is my guess about those numbers. The new version is inserted, in a new block if there is no free space in the same block. The old version is updated. And the index must be maintained. Those are 3 blocks to modify. Here, the row was directly accessed through its TID. But we must find the index entry. The row contains the index value, and then an index scan is possible: two block reads for this small index having one branch only.<\/p>\n<h3>SELECT again<\/h3>\n<p>I said that with Oracle the row is updated in-place and doesn&#8217;t need further cleanup. If I run the same SELECT as the one I did before the UPDATE, I still have only one block to read:<\/p>\n<pre><code>\nPLAN_TABLE_OUTPUT\n------------------------------------------------------------------------------------------------------------------------------------------------------\nSQL_ID  8mj3ms08x0sfh, child number 0\n-------------------------------------\nselect \/*+  *\/  a from demo1  where rowid='AAAR4WAAMAAAAEaAAF'\n-----------------------------------------------------------------------------------------------------------\n| Id  | Operation                  | Name  | Starts | E-Rows | Cost (%CPU)| A-Rows |   A-Time   | Buffers |\n-----------------------------------------------------------------------------------------------------------\n|   0 | SELECT STATEMENT           |       |      1 |        |     1 (100)|      1 |00:00:00.01 |       1 |\n|   1 |  TABLE ACCESS BY USER ROWID| DEMO1 |      1 |      1 |     1   (0)|      1 |00:00:00.01 |       1 |\n-----------------------------------------------------------------------------------------------------------\nColumn Projection Information (identified by operation id):\n-----------------------------------------------------------\n   1 - \"A\"[NUMBER,22]\n<\/code><\/pre>\n<p>In Postgres, because the update was processed as insert+delete, running the same also reads only one block, but it returns no rows:<\/p>\n<pre><code>\nexplain (analyze,verbose,costs,buffers) select  a from demo1  where ctid='(142,6)' ;\n                                              QUERY PLAN\n------------------------------------------------------------------------------------------------------\n Tid Scan on public.demo1  (cost=0.00..4.01 rows=1 width=4) (actual time=0.014..0.014 rows=0 loops=1)\n   Output: a\n   TID Cond: (demo1.ctid = '(142,6)'::tid)\n   Buffers: shared hit=1\n Planning time: 0.442 ms\n Execution time: 0.028 ms\n<\/code><\/pre>\n<p>The new version is in another block, then the TID to find it is different:<\/p>\n<pre><code>\nselect ctid from demo1  where n=1000;\n   ctid\n----------\n (1428,5)\n(1 row)\n<\/code><\/pre>\n<p>There was not enough space for another version of the whole row within the same block. Free space was found in the last block (1428). Of course, this is why the index was updated even if the indexed column did not change: it had to address a different block.<\/p>\n<p>Let&#8217;s query with the new TID:<\/p>\n<pre><code>\nexplain (analyze,verbose,costs,buffers) select  a from demo1  where ctid='(1428,5)' ;\n                                              QUERY PLAN\n------------------------------------------------------------------------------------------------------\n Tid Scan on public.demo1  (cost=0.00..4.01 rows=1 width=4) (actual time=0.008..0.008 rows=1 loops=1)\n   Output: a\n   TID Cond: (demo1.ctid = '(1428,5)'::tid)\n   Buffers: shared hit=1\n Planning time: 0.449 ms\n Execution time: 0.023 ms\n<\/code><\/pre>\n<p>Only one buffer read. However, as we have seen with the <a href=\"https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-ii\/\" target=\"_blank\" rel=\"noopener noreferrer\">Index Only Scan<\/a>, there is a need for cleanup to avoid Heap Fetches. There are also the old tuples that should be removed later or the updated tables and indexes grow forever.<\/p>\n<p>There&#8217;s only one Postgres access path remaining. That&#8217;s for the <a href=\"https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-x\/\" target=\"_blank\" rel=\"noopener noreferrer\">last post<\/a> of this series, which will include the table of content.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>By Franck Pachot . In the previous post we have seen the cheapest way to get one row, reading only one block from its physical location. But that&#8217;s the optimal case where the row has not moved. I&#8217;ll (nearly) conclude this series about access path with an update.<\/p>\n","protected":false},"author":27,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[59,83],"tags":[348,96,77],"type_dbi":[],"class_list":["post-10449","post","type-post","status-publish","format-standard","hentry","category-oracle","category-postgresql","tag-execution-plan","tag-oracle","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>Postgres vs. Oracle access paths X - Update - 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\/postgres-vs-oracle-access-paths-x-update\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Postgres vs. Oracle access paths X - Update\" \/>\n<meta property=\"og:description\" content=\"By Franck Pachot . In the previous post we have seen the cheapest way to get one row, reading only one block from its physical location. But that&#8217;s the optimal case where the row has not moved. I&#8217;ll (nearly) conclude this series about access path with an update.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-x-update\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2017-08-24T18:03:34+00:00\" \/>\n<meta name=\"author\" content=\"Oracle Team\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Oracle Team\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 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\/postgres-vs-oracle-access-paths-x-update\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-x-update\/\"},\"author\":{\"name\":\"Oracle Team\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee\"},\"headline\":\"Postgres vs. Oracle access paths X &#8211; Update\",\"datePublished\":\"2017-08-24T18:03:34+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-x-update\/\"},\"wordCount\":766,\"commentCount\":0,\"keywords\":[\"Execution plan\",\"Oracle\",\"PostgreSQL\"],\"articleSection\":[\"Oracle\",\"PostgreSQL\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-x-update\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-x-update\/\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-x-update\/\",\"name\":\"Postgres vs. Oracle access paths X - Update - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\"},\"datePublished\":\"2017-08-24T18:03:34+00:00\",\"author\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-x-update\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-x-update\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-x-update\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/www.dbi-services.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Postgres vs. Oracle access paths X &#8211; Update\"}]},{\"@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\/66ab87129f2d357f09971bc7936a77ee\",\"name\":\"Oracle Team\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g\",\"caption\":\"Oracle Team\"},\"url\":\"https:\/\/www.dbi-services.com\/blog\/author\/oracle-team\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Postgres vs. Oracle access paths X - Update - 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\/postgres-vs-oracle-access-paths-x-update\/","og_locale":"en_US","og_type":"article","og_title":"Postgres vs. Oracle access paths X - Update","og_description":"By Franck Pachot . In the previous post we have seen the cheapest way to get one row, reading only one block from its physical location. But that&#8217;s the optimal case where the row has not moved. I&#8217;ll (nearly) conclude this series about access path with an update.","og_url":"https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-x-update\/","og_site_name":"dbi Blog","article_published_time":"2017-08-24T18:03:34+00:00","author":"Oracle Team","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Oracle Team","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-x-update\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-x-update\/"},"author":{"name":"Oracle Team","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee"},"headline":"Postgres vs. Oracle access paths X &#8211; Update","datePublished":"2017-08-24T18:03:34+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-x-update\/"},"wordCount":766,"commentCount":0,"keywords":["Execution plan","Oracle","PostgreSQL"],"articleSection":["Oracle","PostgreSQL"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-x-update\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-x-update\/","url":"https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-x-update\/","name":"Postgres vs. Oracle access paths X - Update - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"datePublished":"2017-08-24T18:03:34+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-x-update\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-x-update\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/postgres-vs-oracle-access-paths-x-update\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Postgres vs. Oracle access paths X &#8211; Update"}]},{"@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\/66ab87129f2d357f09971bc7936a77ee","name":"Oracle Team","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g","caption":"Oracle Team"},"url":"https:\/\/www.dbi-services.com\/blog\/author\/oracle-team\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/10449","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\/27"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=10449"}],"version-history":[{"count":0,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/10449\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=10449"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=10449"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=10449"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=10449"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}