<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/https/speakerdeck.com/feed.atom.xml" media="screen"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <id>tag:speakerdeck.com,2005:/peterg</id>
  <link rel="alternate" type="text/html" href="https://speakerdeck.com"/>
  <link rel="self" type="application/atom+xml" href="https://speakerdeck.com/peterg.atom"/>
  <entry>
    <id>tag:speakerdeck.com,2005:Talk/1370566</id>
    <published>2025-05-16T17:37:43-04:00</published>
    <updated>2025-05-16T17:39:50-04:00</updated>
    <link rel="alternate" type="text/html" href="https://speakerdeck.com/peterg/multidimensional-search-talk-pgconfdev"/>
    <title>multidimensional-search-talk-pgconfdev</title>
    <content type="html"></content>
<media:thumbnail url="https://files.speakerdeck.com/presentations/311172eb61d342a09d7f0f63731b94bf/preview_slide_0.jpg?35116194" width='' height='' xmlns:media='http://search.yahoo.com/mrss/'></media:thumbnail>    <author>
      <name>Peter Geoghegan (@peterg)</name>
    </author>
  </entry>
  <entry>
    <id>tag:speakerdeck.com,2005:Talk/1004188</id>
    <published>2023-03-10T12:03:08-05:00</published>
    <updated>2023-04-03T19:54:53-04:00</updated>
    <link rel="alternate" type="text/html" href="https://speakerdeck.com/peterg/bloat-postgresql-scale"/>
    <title>bloat-postgresql-scale</title>
    <content type="html">https://www.socallinuxexpo.org/scale/20x/presentations/bloat-postgresql-taxonomy

Video of talk: https://www.youtube.com/watch?v=JDG4bMHxCH8

PostgreSQL's approach to transaction management uses MVCC (multi-version concurrency control). Postgres often maintains multiple physical versions of a single logical row. This is used to reconstruct the logical contents of tables at a specific point in time for SQL queries (zero or one row versions should be visible for each logical row). MVCC avoids having readers block writers and writers block readers, a frequent problem with database systems that use traditional 2PL. However, there is a cost to this approach: bloat must eventually be removed and reclaimed, typically by an autovacuum worker process.

Most Postgres DBAs are familiar with bloat, and almost as many will have some experience with tuning autovacuum to better manage it. There have been quite a few talks about the practical aspects of optimizing autovacuum and avoiding bloat; this talk isn't one of them. Instead, the goal of the talk is to show how bloat can accumulate, what that looks like at the page level and at the level of entire tables and indexes, and how that may impact production queries.

The talk covers:

How VACUUM processes each structure, and in what order.

How the HOT optimization works.

How Postgres manages free space.

The design of VACUUM. What space/bloat management tasks are prioritized by VACUUM, and why this makes sense.</content>
<media:thumbnail url="https://files.speakerdeck.com/presentations/2f5c00e99cfc4d819c6671ae957f965d/preview_slide_0.jpg?24829483" width='' height='' xmlns:media='http://search.yahoo.com/mrss/'></media:thumbnail>    <author>
      <name>Peter Geoghegan (@peterg)</name>
    </author>
  </entry>
  <entry>
    <id>tag:speakerdeck.com,2005:Talk/876415</id>
    <published>2022-05-26T22:12:22-04:00</published>
    <updated>2023-11-29T16:14:14-05:00</updated>
    <link rel="alternate" type="text/html" href="https://speakerdeck.com/peterg/logical-database"/>
    <title>logical-database</title>
    <content type="html">Video of talk on YouTube: https://www.youtube.com/watch?v=QeiOv6j0Jws

&lt;b&gt;Thinking about the logical database&lt;/b&gt;

https://www.pgcon.org/events/pgcon_2022/schedule/session/308-thinking-about-the-logical-database/

When it comes to the design of the internal components of PostgreSQL, history matters. Earlier designs create ripples that affect later designs.

Extensible indexing created the need for VACUUM, since without VACUUM it is far from obvious how transaction rollback could ever work, at least with GiST and GIN indexes. Transaction rollback that is decoupled from the physical representation of data (compared to traditional designs based on two-phase locking) was necessary even before Postgres added multi-version concurrency control.

This talk will describe a conceptual framework for discussing whether something is an essential part of storing data transactionally from the point of view of users, or whether it is an inessential implementation detail of transaction management and storage, that could in principle be implemented in many different ways. The former can be categorized as belonging to the logical database, while the latter can be categorized as belonging to the physical database.

Recent improvements in how the standard B-Tree index access method performs garbage collection to control MVCC version bloat (authored by the speaker) drew upon these concepts. But almost any improvement to the on-disk representation of either tables or indexes has some kind of tension between the logical and physical database. The talk explores the "logical database, physical database" concepts by discussing this recent work, as well as pending work on free space management in the standard heap table access method.</content>
<media:thumbnail url="https://files.speakerdeck.com/presentations/63f74ef8973e479ab4de3fc32e648136/preview_slide_0.jpg?21552801" width='' height='' xmlns:media='http://search.yahoo.com/mrss/'></media:thumbnail>    <author>
      <name>Peter Geoghegan (@peterg)</name>
    </author>
  </entry>
  <entry>
    <id>tag:speakerdeck.com,2005:Talk/673356</id>
    <published>2020-10-13T21:19:08-04:00</published>
    <updated>2020-10-13T21:20:20-04:00</updated>
    <link rel="alternate" type="text/html" href="https://speakerdeck.com/peterg/postgresql-deduplication-2020"/>
    <title>postgresql-deduplication-2020</title>
    <content type="html">B-Tree deduplication in PostgreSQL 13:  design and background</content>
<media:thumbnail url="https://files.speakerdeck.com/presentations/b2451f02c3de4ad390642c06ae4c964e/preview_slide_0.jpg?16471945" width='' height='' xmlns:media='http://search.yahoo.com/mrss/'></media:thumbnail>    <author>
      <name>Peter Geoghegan (@peterg)</name>
    </author>
  </entry>
  <entry>
    <id>tag:speakerdeck.com,2005:Talk/565176</id>
    <published>2019-10-17T04:56:23-04:00</published>
    <updated>2019-10-17T04:57:21-04:00</updated>
    <link rel="alternate" type="text/html" href="https://speakerdeck.com/peterg/xact-rollback-pgconfeu"/>
    <title>xact-rollback-pgconfeu</title>
    <content type="html">https://www.postgresql.eu/events/pgconfeu2019/schedule/session/2742-instantaneous-transaction-rollback-and-other-advantages-of-versioned-storage/</content>
<media:thumbnail url="https://files.speakerdeck.com/presentations/ccf86d229c9d40cf83deb4945536f30e/preview_slide_0.jpg?13900749" width='' height='' xmlns:media='http://search.yahoo.com/mrss/'></media:thumbnail>    <author>
      <name>Peter Geoghegan (@peterg)</name>
    </author>
  </entry>
  <entry>
    <id>tag:speakerdeck.com,2005:Talk/520257</id>
    <published>2019-05-30T08:40:50-04:00</published>
    <updated>2019-08-20T15:28:52-04:00</updated>
    <link rel="alternate" type="text/html" href="https://speakerdeck.com/peterg/nbtree-arch-pgcon"/>
    <title>nbtree-arch-pgcon</title>
    <content type="html">nbtree: An architectural perspective

Video (lacks original animations): https://www.youtube.com/watch?v=p5RaATILoiE

Many PostgreSQL users have a basic understanding of how Postgres nbtree indexes work internally (e.g., how the structure is maintained, high level details of how a new level is added to the tree, the role of VACUUM in garbage collection). A smaller number have some understanding of advanced topics (e.g., details of Lehman &amp; Yao's B-Link technique, details of crash recovery). Even an experienced backend hacker could be forgiven for concluding that this is all well explored territory, leaving little room for improvement, since all the important components are already in place.

This view of things is based on a correct premise, and yet cannot explain why nbtree doesn't perform well with certain specific real world workloads. For example, there is an excessive amount of nbtree index bloat created by the industry standard TPC-C benchmark, despite the fact that TPC's transactions rarely update indexed columns, and therefore handily avoid so-called "write amplification". Certain pieces are missing.

Code enhancements (authored by the speaker) that will appear in PostgreSQL 12 will significantly improve matters for affected workloads. In some ways, this work is based on a return to decades old fundamentals. In other ways, it is based on practical experience, involving analyzing real-world index structures in an effort to learn where problems may lie.

This talk will cover:

• A review of the design of nbtree, especially its high level goals.

• The importance of thinking in terms of invariants — the rules underlying what belongs where in the index.

• Interesting ways in which nbtree exceeds what is truly required by the invariants, and how that can be exploited to improve performance.

• Possible future work aimed at reducing CPU cache misses while descending a B-Tree.

• The big picture — how all these techniques are complementary, and worth more than the sum of their parts</content>
<media:thumbnail url="https://files.speakerdeck.com/presentations/931c3f5a93784a37a8445e0be1280b9f/preview_slide_0.jpg?13359084" width='' height='' xmlns:media='http://search.yahoo.com/mrss/'></media:thumbnail>    <author>
      <name>Peter Geoghegan (@peterg)</name>
    </author>
  </entry>
  <entry>
    <id>tag:speakerdeck.com,2005:Talk/472536</id>
    <published>2018-10-26T05:14:32-04:00</published>
    <updated>2018-10-26T05:22:06-04:00</updated>
    <link rel="alternate" type="text/html" href="https://speakerdeck.com/peterg/bloat-postgresql-pgconfeu"/>
    <title>bloat-postgresql-pgconfeu</title>
    <content type="html"></content>
<media:thumbnail url="https://files.speakerdeck.com/presentations/401b65c7e5074132b9e274a1780852b2/preview_slide_0.jpg?11063950" width='' height='' xmlns:media='http://search.yahoo.com/mrss/'></media:thumbnail>    <author>
      <name>Peter Geoghegan (@peterg)</name>
    </author>
  </entry>
  <entry>
    <id>tag:speakerdeck.com,2005:Talk/463068</id>
    <published>2018-09-07T03:26:18-04:00</published>
    <updated>2018-09-07T03:27:52-04:00</updated>
    <link rel="alternate" type="text/html" href="https://speakerdeck.com/peterg/bloat-postgresql-pgopen"/>
    <title>bloat-postgresql-pgopen</title>
    <content type="html"></content>
<media:thumbnail url="https://files.speakerdeck.com/presentations/e6116cfa0ac7483291061073dc1cae88/preview_slide_0.jpg?10712710" width='' height='' xmlns:media='http://search.yahoo.com/mrss/'></media:thumbnail>    <author>
      <name>Peter Geoghegan (@peterg)</name>
    </author>
  </entry>
  <entry>
    <id>tag:speakerdeck.com,2005:Talk/396013</id>
    <published>2017-06-15T19:42:32-04:00</published>
    <updated>2017-06-15T19:44:15-04:00</updated>
    <link rel="alternate" type="text/html" href="https://speakerdeck.com/peterg/query-evaluation-pwl"/>
    <title>query-evaluation-pwl</title>
    <content type="html">Presentation on Goetz Graefe's "Query Evaluation Techniques for Large Databases" paper for Papers We Love.

https://www.meetup.com/papers-we-love-too/events/237686185/</content>
<media:thumbnail url="https://files.speakerdeck.com/presentations/9da878a5e8704ae5b0bf6223222c257f/preview_slide_0.jpg?8146637" width='' height='' xmlns:media='http://search.yahoo.com/mrss/'></media:thumbnail>    <author>
      <name>Peter Geoghegan (@peterg)</name>
    </author>
  </entry>
  <entry>
    <id>tag:speakerdeck.com,2005:Talk/385479</id>
    <published>2017-03-29T10:13:42-04:00</published>
    <updated>2017-05-16T21:28:06-04:00</updated>
    <link rel="alternate" type="text/html" href="https://speakerdeck.com/peterg/sort-hash-pgconfus-2017"/>
    <title>sort-hash-pgconfus-2017</title>
    <content type="html">Video: https://www.youtube.com/watch?v=aic_9KNwKn0

PostgreSQL 9.5 and 9.6 significantly improved upon the performance of both hash joins, and sort operations. Sorts are often used as input to GroupAggregate nodes and merge joins. While both approaches have various strengths and weaknesses, and are essential components of the PostgreSQL executor, their relative importance has somewhat shifted over the years. This happened due to trends in CPU and storage performance characteristics, and various improvements that gradually made their way into Postgres.

Capabilities expected to be part of PostgreSQL 10 may further complicate this picture; parallel hash join and parallel sort add another dimension that must be considered. This may force us to further revise the "Sort vs. Hash" analysis in the coming years.

In this talk, I'll discuss:

* Why merge joins may be faster than hash joins for particular cases, and vice-versa. (Nested-loop joins will be briefly discussed.)

* Improvements that have been made in both areas, and improvements that are tentatively scheduled for the next Postgres release.

* How to conceptualize both approaches, to understand why the optimizer may prefer one or the other of the two general approaches in practice.

* A historical perspective: the waxing and waning of sort merge join since the 1970s.</content>
<media:thumbnail url="https://files.speakerdeck.com/presentations/bd27592aa1204383ab4510b4c114a08d/preview_slide_0.jpg?7753214" width='' height='' xmlns:media='http://search.yahoo.com/mrss/'></media:thumbnail>    <author>
      <name>Peter Geoghegan (@peterg)</name>
    </author>
  </entry>
  <entry>
    <id>tag:speakerdeck.com,2005:Talk/368338</id>
    <published>2016-11-14T23:15:43-05:00</published>
    <updated>2017-04-07T20:17:18-04:00</updated>
    <link rel="alternate" type="text/html" href="https://speakerdeck.com/peterg/sort-hash-pgconfsv"/>
    <title>sort-hash-pgconfsv</title>
    <content type="html">Video: https://www.youtube.com/watch?v=w2Lu3KMOG98

Sort vs. Hash: A Duality

PostgreSQL 9.5 and 9.6 significantly improved upon the performance of both hash joins, and sort operations. Sorts are often used as input to GroupAggregate nodes and merge joins. While both approaches have various strengths and weaknesses, and are essential components of the PostgreSQL executor, their relative importance has somewhat shifted over the years. This happened due to trends in CPU and storage performance characteristics, and various improvements that gradually made their way into Postgres.

Capabilities expected to be part of PostgreSQL 10 may further complicate this picture; parallel hash join and parallel sort add another dimension that must be considered. This may force us to further revise the "Sort vs. Hash" analysis in the coming years.

In this talk, I'll discuss:

* Why merge joins may be faster than hash joins for particular cases, and vice-versa. (Nested-loop joins will be briefly discussed.)

* Improvements that have been made in both areas, and improvements that are tentatively scheduled for the next Postgres release.

* How to conceptualize both approaches, to understand why the optimizer may prefer one or the other of the two general approaches in practice.

* A historical perspective: the waxing and waning of sort merge join since the 1970s.</content>
<media:thumbnail url="https://files.speakerdeck.com/presentations/061ac9b09abf446687ad3f1b776388f5/preview_slide_0.jpg?7194529" width='' height='' xmlns:media='http://search.yahoo.com/mrss/'></media:thumbnail>    <author>
      <name>Peter Geoghegan (@peterg)</name>
    </author>
  </entry>
  <entry>
    <id>tag:speakerdeck.com,2005:Talk/312329</id>
    <published>2015-09-19T16:40:55-04:00</published>
    <updated>2015-09-19T16:41:23-04:00</updated>
    <link rel="alternate" type="text/html" href="https://speakerdeck.com/peterg/sorting-improvements-in-postgresql-9-dot-5-and-9-dot-6"/>
    <title>Sorting improvements in PostgreSQL 9.5 and 9.6</title>
    <content type="html"></content>
<media:thumbnail url="https://files.speakerdeck.com/presentations/852dbf70b233461eadd8109b84f07d08/preview_slide_0.jpg?5267419" width='' height='' xmlns:media='http://search.yahoo.com/mrss/'></media:thumbnail>    <author>
      <name>Peter Geoghegan (@peterg)</name>
    </author>
  </entry>
  <entry>
    <id>tag:speakerdeck.com,2005:Talk/312328</id>
    <published>2015-09-19T16:37:07-04:00</published>
    <updated>2016-02-06T09:06:45-05:00</updated>
    <link rel="alternate" type="text/html" href="https://speakerdeck.com/peterg/upsert-use-cases"/>
    <title>UPSERT use-cases</title>
    <content type="html">Ecobox
Home
Blog
About
Tickets
Sessions
Venue &amp; Hotel
Sponsors

POSTGRES OPEN
SEPT 16TH - 18TH ・ DALLAS

UPSERT use cases

Back
Date: Sept. 18, 2015
Time: 13:30 - 14:20
Room: Houston Ballroom B/C
Level: Intermediate
Feedback: Leave feedback
PostgreSQL 9.5 will have support for a feature that is popularly known as "UPSERT" - the ability to either insert or update a row according to whether an existing row with the same key exists. If such a row already exists, the implementation should update it. If not, a new row should be inserted. This is supported by way of a new high level syntax (a clause that extends the INSERT statement) that more or less relieves the application developer from having to give any thought to race conditions. This common operation for client applications is set to become far simpler and far less error-prone than legacy ad-hoc approaches to UPSERT involving subtransactions. Moreover, the new implementation performs much better than those legacy approaches.

While the feature is most obviously compelling for OLTP and web application use cases, it's also true that the syntax is powerful enough to be very useful in many real world data integration scenarios. The non-standard PostgreSQL syntax offer explicit, fine grained control over where and how to update. For example, an update may not actually affect an existing row due to not satisfying some additional criteria (i.e. due to not passing the ON CONFLICT ... DO UPDATE special, dedicated WHERE clause).

This talk gives an overview of the feature from a high level, and examines these use cases. You will learn how you might want to use the new UPSERT feature in your application beyond the obvious. In passing, there will be brief discussion of why UPSERT's implementation proved to be a hard problem, and, relatedly, why a custom syntax was used instead of the SQL standard's MERGE syntax.</content>
<media:thumbnail url="https://files.speakerdeck.com/presentations/02c13140b59749a49f2bcaa7fe8607bc/preview_slide_0.jpg?5850596" width='' height='' xmlns:media='http://search.yahoo.com/mrss/'></media:thumbnail>    <author>
      <name>Peter Geoghegan (@peterg)</name>
    </author>
  </entry>
  <entry>
    <id>tag:speakerdeck.com,2005:Talk/301257</id>
    <published>2015-05-31T00:08:48-04:00</published>
    <updated>2015-05-31T00:10:12-04:00</updated>
    <link rel="alternate" type="text/html" href="https://speakerdeck.com/peterg/upsert-in-postgresql"/>
    <title>"UPSERT" in PostgreSQL</title>
    <content type="html">Small talk covering the "UPSERT" feature coming in PostgreSQL 9.5.

https://www.youtube.com/watch?v=pbg97bkxbbY</content>
<media:thumbnail url="https://files.speakerdeck.com/presentations/35b2e5a5c957497a809f76024b68b969/preview_slide_0.jpg?4863701" width='' height='' xmlns:media='http://search.yahoo.com/mrss/'></media:thumbnail>    <author>
      <name>Peter Geoghegan (@peterg)</name>
    </author>
  </entry>
  <entry>
    <id>tag:speakerdeck.com,2005:Talk/106822</id>
    <published>2014-06-25T12:21:30-04:00</published>
    <updated>2014-06-25T12:22:25-04:00</updated>
    <link rel="alternate" type="text/html" href="https://speakerdeck.com/peterg/jsonb-deep-dive"/>
    <title>jsonb Deep Dive</title>
    <content type="html">Peter Geoghegan, one of the major developers of the new "JSONB" binary, indexable JSON type for PostgreSQL 9.4, will be in town and will guide SFPUG members in a "deep dive" into the new technology, including:

• Both the new JSONB type and the old JSON type input and output JSON, so what's the difference?
• What new features does it offer?
• How is the new data type structured, and how does it work?
• How do you index JSONB? 
• What things remain unimplemented?

Before the main event, we will have a Lightning Talk by Eric Ongerth: Running PostgreSQL in a Docker Container 
Food and Drink, as well as Peter's travel, are sponsored by Heroku.  It is being hosted by SwitchFly. </content>
<media:thumbnail url="https://files.speakerdeck.com/presentations/a79cd060deb20131ffed2ad9291baba4/preview_slide_0.jpg?3208791" width='' height='' xmlns:media='http://search.yahoo.com/mrss/'></media:thumbnail>    <author>
      <name>Peter Geoghegan (@peterg)</name>
    </author>
  </entry>
  <entry>
    <id>tag:speakerdeck.com,2005:Talk/67764</id>
    <published>2013-09-20T14:22:15-04:00</published>
    <updated>2013-10-12T15:34:04-04:00</updated>
    <link rel="alternate" type="text/html" href="https://speakerdeck.com/peterg/concurrency-in-postgres"/>
    <title>Concurrency in Postgres</title>
    <content type="html">Talk that examines handling of concurrency issues in Postgres, and how Postgres 9.3 improves situation surrounding foreign key locks.

(See http://postgresopen.org/2013/schedule/presentations/366/)</content>
<media:thumbnail url="https://files.speakerdeck.com/presentations/2fb3cf40044f0131e7a8164d946a58d9/preview_slide_0.jpg?1996650" width='' height='' xmlns:media='http://search.yahoo.com/mrss/'></media:thumbnail>    <author>
      <name>Peter Geoghegan (@peterg)</name>
    </author>
  </entry>
  <title>Peter Geoghegan (@peterg) on Speaker Deck</title>
  <updated>2025-05-16T17:37:43-04:00</updated>
</feed>
