<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>RustProof Labs blog planet-postgresql posts</title><link>https://blog.rustprooflabs.com/rss/planet-postgresql</link><description>RustProof Labs: blogging for knowledge is a technical blog focused on PostgreSQL, data, and other technical interests.</description><language>en-US</language><copyright>© RustProof Labs</copyright><lastBuildDate>Wed, 18 Mar 2026 13:11:38 GMT</lastBuildDate><generator>rfeed v1.1.1</generator><docs>https://github.com/svpino/rfeed/blob/master/README.md</docs><item><title>PostgreSQL: Integers, on-disk order, and performance</title><link>https://blog.rustprooflabs.com/2020/08/postgres-integer-index-performance</link><description>&lt;p&gt;This post examines how the on-disk order of integer data can influence performance
in PostgreSQL. When working with relational databases, you often do not need to
think about data storage, though there are times when these details can have a noticeable impact on your database's performance.&lt;/p&gt;
&lt;p&gt;This post uses PostgreSQL 12.3 on Ubuntu 18.04 on a DigitalOcean droplet with 4 CPU and 8 GB RAM droplet, aka "Rig B" from &lt;a href="/2019/10/osm2pgsql-scaling"&gt;Scaling osm2pgsql: Process and costs&lt;/a&gt;.&lt;/p&gt;
</description><pubDate>Wed, 05 Aug 2020 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2020/08/postgres-integer-index-performance</guid></item><item><title>Updated for 2020: Load OpenStreetMap data to PostGIS</title><link>https://blog.rustprooflabs.com/2020/01/postgis-osm-load-2020</link><description>&lt;p&gt;I originally wrote about
how to &lt;a href="/2019/01/postgis-osm-load"&gt;load OpenStreetMap data into PostGIS&lt;/a&gt;
just under one year ago.
Between then and now, 364 days, a number of major changes have
occurred in the form of new versions of all the software involved.
Due to the combination of changes I decided to write an updated
version of the post.  After all, I was no longer able to copy/paste my own
post as part of my procedures!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Update, January 2, 2021:  This post documents the original "pgsql" output of osm2pgsql.  I am no longer using this method for my OpenStreetMap data in PostGIS. The new &lt;a href="postgis-openstreetmap-flex-structure"&gt;osm2pgsql Flex output and PgOSM-Flex project&lt;/a&gt; provides a superior experience and improved final quality of data.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The goal of this post is to cover the typical machine and configuration
I use to load OpenStreetMap data into PostGIS with the latest versions.
The first part of the post covers the how of setting up and loading
OpenStreetMap data to PostGIS.
The second portion explains a bit of the reasoning of why I do
things this way. The latest versions of the software at this time are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PostgreSQL 12&lt;/li&gt;
&lt;li&gt;PostGIS 3&lt;/li&gt;
&lt;li&gt;osm2pgsql 1.2&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;This post is part of the series &lt;a href="/2018/06/pg-series-toc"&gt;&lt;em&gt;PostgreSQL:  From Idea to Database&lt;/em&gt;&lt;/a&gt;. Also, see our recorded session &lt;a href="/2020/01/webinar-load-postgis-with-osm2pgsql"&gt;Load PostGIS with osm2pgsql&lt;/a&gt; for similar content in video format.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Changes to software&lt;/h2&gt;
&lt;p&gt;PostgreSQL 12, PostGIS 3, and osm2pgsql 1.2 are all new releases
since the original post. The original used Postgres 11, PostGIS 2.5 and
osm2pgsql 0.94.  If you just look at the version numbers they may look like small increases, but the whole package is chock-full of improvements!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you can upgrade to the latest and greatest, I recommend you do so!&lt;/p&gt;
&lt;/blockquote&gt;
</description><pubDate>Sat, 04 Jan 2020 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2020/01/postgis-osm-load-2020</guid></item><item><title>Hands on with osm2pgsql's new Flex output</title><link>https://blog.rustprooflabs.com/2020/12/osm2gpsql-flex-output-to-postgis</link><description>&lt;p&gt;The &lt;a href="https://github.com/openstreetmap/osm2pgsql"&gt;osm2pgsql project&lt;/a&gt; has seen quite a bit of development over the past couple of years.  This is a core piece of software
used by a large number of people to load OpenStreetMap data into
PostGIS / PostgreSQL databases, so it has been great to see the activity and improvements.  Recently, I was contacted by Jochen Topf to see
if I would give one of those (big!) improvements,
&lt;a href="https://blog.jochentopf.com/2020-05-10-new-flex-output-in-osm2pgsql.html"&gt;osm2pgsql's new Flex output&lt;/a&gt;,
a try.  While the flex output is still marked as "experimental" it is already
quite robust.  In fact, I have already started thinking of the typical pgsql
output I have used for nearly a decade as "the old output!"&lt;/p&gt;
&lt;p&gt;So what does this new Flex output do for us?  It gives us control over
the imported data's format, structure and quality. This process uses Lua
styles (scripts) to achieve powerful results.
The legacy pgsql output from osm2pgsql
gave you three (3) main tables with everything organized into points, lines
and polygons, solely by geometry type.  From a database design perspective
this would be like keeping product prices,
employee salaries and expense reports all in one table using the justification
"they all deal with money."  With the flex output we are no longer constrained by
this legacy design.  With that in mind, the rest of this post explores 
osm2pgsql's Flex output.&lt;/p&gt;
</description><pubDate>Thu, 10 Dec 2020 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2020/12/osm2gpsql-flex-output-to-postgis</guid></item><item><title>Large Text in PostgreSQL: Performance and Storage</title><link>https://blog.rustprooflabs.com/2020/07/postgres-storing-large-text</link><description>&lt;p&gt;Storing large amounts of data in a single cell in the database
has long been a point of discussion.  This topic has
surfaced in the form of design questions
in database projects I have been involved with over the years.
Often, it surfaces as a request to store images, PDFs, or other 
"non-relational" data directly in the database.
I was an advocate for storing files on the file system
for many, if not all, of those scenarios.&lt;/p&gt;
&lt;p&gt;Then, after years of working with PostGIS data
I had the realization that much of my vector data that performs
so well when properly structured and queried, was larger and more complex
than many other blobs of data I had previously resisted.
Two years ago I made the decision to store images in a production database
using &lt;code&gt;BYTEA&lt;/code&gt;. We can guarantee there are a limited number of images
with a controlled maximum resolution (limiting size) and a specific use
case.  There was also the knowledge that caching the images in the frontend
would be an easy solution if performance started declining.
This system is approaching two years in production with great performance.
I am so glad the project has a singular data source:  PostgreSQL!&lt;/p&gt;
</description><pubDate>Sun, 05 Jul 2020 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2020/07/postgres-storing-large-text</guid></item><item><title>Find your local SRID in PostGIS</title><link>https://blog.rustprooflabs.com/2020/11/postgis-find-local-srid</link><description>&lt;p&gt;The past few weeks I had been tossing around some ideas that resulted in me
looking for a particular data set.  I needed to get the
&lt;a href="https://en.wikipedia.org/wiki/Minimum_bounding_rectangle"&gt;bounding boxes&lt;/a&gt;
for the most commonly used SRIDs
(&lt;a href="https://desktop.arcgis.com/en/arcmap/10.3/manage-data/using-sql-with-gdbs/what-is-an-srid.htm"&gt;&lt;strong&gt;S&lt;/strong&gt;patial &lt;strong&gt;R&lt;/strong&gt;eference &lt;strong&gt;ID&lt;/strong&gt;entifier&lt;/a&gt;)
in PostGIS to join with the
&lt;code&gt;public.spatial_ref_sys&lt;/code&gt; table.  My hope was to be able to use the data to quickly identify local
SRIDs for geometries spreading across the U.S.  This data was needed to support
another idea where I want both accurate spatial calculations and the best possible 
performance when working with large OpenStreetMap data sets.&lt;/p&gt;
&lt;p&gt;The good news is now I have the exact data I was looking for.  The unexpected bonus is that there is a much broader use case for this data
in providing an &lt;strong&gt;easy&lt;/strong&gt; way to find which SRIDs might be appropriate for a specific area!  &lt;/p&gt;
&lt;p&gt;This post explores this new data with an example of how to use it with pre-existing
spatial data.&lt;/p&gt;
</description><pubDate>Wed, 04 Nov 2020 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2020/11/postgis-find-local-srid</guid></item><item><title>PostgreSQL 13Beta3: B-Tree index deduplication</title><link>https://blog.rustprooflabs.com/2020/09/postgres-beta3-btree-dedup</link><description>&lt;p&gt;PostgreSQL 13 development is coming along nicely, Postgres 13 Beta3 was
&lt;a href="https://www.postgresql.org/about/news/2060/"&gt;released on 8/13/2020&lt;/a&gt;.
The Postgres Beta 1 and 2 releases were released in May and June 2020.
One of the features that has my interest in Postgres 13 is the B-Tree deduplication effort.  B-Tree indexes are the default indexing method
in Postgres, and are likely the most-used indexes in production 
environments.
Any improvements to this part of the database are likely to have wide-reaching benefits.
Removing duplication from indexes keeps their physical size smaller,
reduces I/O overhead, and should help keep &lt;code&gt;SELECT&lt;/code&gt; queries fast!&lt;/p&gt;
</description><pubDate>Sun, 06 Sep 2020 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2020/09/postgres-beta3-btree-dedup</guid></item><item><title>Postgres 13 Performance with OpenStreetMap data</title><link>https://blog.rustprooflabs.com/2020/10/postgres13-openstreetmap-performance</link><description>&lt;p&gt;With &lt;a href="https://www.postgresql.org/docs/13/release-13.html"&gt;Postgres 13 released&lt;/a&gt;
recently, a new season of testing has begun!
I recently wrote about the &lt;a href="/2020/09/postgres-beta3-btree-dedup"&gt;impact of BTree index deduplication&lt;/a&gt;, finding that improvement is a serious win.
This post continues looking at Postgres 13 by examining performance
through a few steps of an OpenStreetMap data (PostGIS) workflow.&lt;/p&gt;
&lt;h2&gt;Reasons to upgrade&lt;/h2&gt;
&lt;p&gt;Performance appears to be a strong advantage to Postgres 13 over Postgres 12. 
&lt;a href="https://www.enterprisedb.com/blog/whats-new-postgresql-13"&gt;Marc Linster wrote&lt;/a&gt; there's "not one headline-grabbing feature, but rather a wide variety of improvements along with updates to previously released features."  I am finding that to be an
appropriate description.
At this point I intend to upgrade our servers for the improved performance,
plus a few other cool benefits.&lt;/p&gt;
</description><pubDate>Mon, 19 Oct 2020 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2020/10/postgres13-openstreetmap-performance</guid></item><item><title>Use PostgreSQL file_fdw to Access External Data</title><link>https://blog.rustprooflabs.com/2020/03/postgresql-fdw-remote-file</link><description>&lt;p&gt;Loading external data is a core task for many database administrators.  With Postgres we have the
powerful option of using
&lt;a href="https://www.postgresql.org/docs/current/ddl-foreign-data.html"&gt;Foreign Data Wrappers&lt;/a&gt; (FDW)
to bring in external data sources.
FDWs allow us to access data that is external to the database by using SQL from within the database.
These external data sources can be in a number of formats, including
other relational databases (Postgres, Oracle, MySQL),
NoSQL sources (MongoDB, Redis), raw data files (csv, JSON) and
&lt;a href="https://wiki.postgresql.org/wiki/Foreign_data_wrappers"&gt;many more&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This post shows how to use
&lt;a href="https://www.postgresql.org/docs/current/file-fdw.html"&gt;&lt;code&gt;file_fdw&lt;/code&gt;&lt;/a&gt;
to load remote data from CSV files available from GitHub. Sharing data
via public source control tools like GitHub has become a common way
to make data sets widely available. Other public data is available
from various government and non-profit sites, so this is a handy tool to have available and reuse.&lt;/p&gt;
&lt;h2&gt;External data source&lt;/h2&gt;
&lt;p&gt;For this post I am using the
COVID-19 data John Hopkins University is curating.  See
&lt;a href="https://github.com/CSSEGISandData/COVID-19"&gt;the main GitHub page&lt;/a&gt; for full attribution
and meta-details about the data.</description><pubDate>Fri, 27 Mar 2020 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2020/03/postgresql-fdw-remote-file</guid></item><item><title>Pi 4 Performance:  PostgreSQL and PostGIS</title><link>https://blog.rustprooflabs.com/2020/03/pi4-performance-postgresql-postgis</link><description>&lt;p&gt;Happy Pi (π) Day!  I decided to celebrate with another post
looking at the Raspberry Pi 4's
performance running Postgres and PostGIS.
A few months ago I added another Raspberry Pi to my collection,
the new Model 4 with 4 GB RAM.  My
&lt;a href="/2019/08/postgresql-pgbench-raspberry-pi-4-initial"&gt;initial review&lt;/a&gt;
focused on &lt;code&gt;pgbench&lt;/code&gt; results comparing the Pi 4 against the previous
3B models as well as the even lower-powered Raspberry Pi Zero W.
This post continues testing the Rasperry Pi 4's performance with
PostgreSQL and PostGIS, this time with a look at a more suitable 
setup for production use cases.
The main difference are the use of an external SSD drive and
full-disk encryption.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Raspberry Pi Logo (Small)" src="/static/images/Raspi-PGB001-sm.png" /&gt;&lt;/p&gt;
&lt;h2&gt;Hardware and Configuration&lt;/h2&gt;
&lt;p&gt;The Raspberry Pi 4 is mounted in an enclosed Cana Kit case
with a small fan in the top running on the 3.3 V rail (lower power),
powered by a dedicated 3.5A power supply.&lt;/p&gt;
</description><pubDate>Sat, 14 Mar 2020 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2020/03/pi4-performance-postgresql-postgis</guid></item><item><title>PostGIS Trajectory: Space plus Time</title><link>https://blog.rustprooflabs.com/2020/11/postgis-trajectory-intro</link><description>&lt;p&gt;A few months ago I started experimenting with a few project ideas
involving data over space and time.  Naturally, I want to use
Postgres and PostGIS as the main workhorse for these projects,
the challenge was working out exactly how to pull it all together.
After a couple false starts I had to put those projects aside for other priorities.
In my free time I have continued working through some related reading on the topic.
I found
&lt;a href="https://anitagraser.com/2018/04/16/movement-data-in-gis-12-why-you-should-be-using-postgis-trajectories/"&gt;why you should be using PostGIS trajectories&lt;/a&gt;
by Anita Graser and recommend reading that before continuing with this post.
In fact, read &lt;a href="https://www.austriaca.at/0xc1aa5576_0x00390cbe"&gt;Evaluating Spatio-temporal Data
Models for Trajectories in PostGIS
Databases&lt;/a&gt;
while you're at it!  There is great information in those resources
with more links to other resources.&lt;/p&gt;
&lt;p&gt;This post outlines examples of how to use these new PostGIS trajectory tricks with
OpenStreetMap data I already have available
(&lt;a href="/2020/01/postgis-osm-load-2020"&gt;load&lt;/a&gt;
and
&lt;a href="https://github.com/rustprooflabs/pgosm"&gt;prepare&lt;/a&gt;
).
Often, trajectory examples assume using data collected from our
new age of IoT sensors sending GPS points and timestamps.  This example approaches
trajectories from a data modeling perpective instead, showing how to synthesize trajectory data using &lt;code&gt;pgrouting&lt;/code&gt;.
Visualization of data is a critical component of sharing information,
&lt;a href="https://qgis.org"&gt;QGIS&lt;/a&gt;
has long been my favorite GIS application to use with PostGIS data.&lt;/p&gt;
</description><pubDate>Sun, 29 Nov 2020 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2020/11/postgis-trajectory-intro</guid></item><item><title>PgDD extension moves to pgrx</title><link>https://blog.rustprooflabs.com/2021/10/pgdd-extension-using-pgx-rust</link><description>&lt;p&gt;Our data dictionary extension, &lt;a href="https://github.com/rustprooflabs/pgdd"&gt;PgDD&lt;/a&gt;,
has been re-written using the &lt;a href="https://github.com/pgcentralfoundation/pgrx"&gt;pgrx framework&lt;/a&gt; in Rust!
At this time I have &lt;a href="https://github.com/rustprooflabs/pgdd/releases/tag/0.4.0.rc3"&gt;tagged &lt;code&gt;0.4.0.rc3&lt;/code&gt;&lt;/a&gt; and just need to do a bit more testing before
the official &lt;code&gt;0.4.0&lt;/code&gt; release.
While I am excited for the news for PgDD, what is more exciting is the
pgrx framework and the ease it brings to developing Postgres extensions!
Getting started with pgrx is straightforward and using &lt;code&gt;cargo pgrx run&lt;/code&gt; makes it
simple to build your extension against multiple versions of Postgres.&lt;/p&gt;
&lt;p&gt;This post outlines how I came to the decision to use pgrx for Postgres extension development.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note:  pgrx was originally named pgx.  This post has been updated to reflect its current name.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Progression of PgDD&lt;/h2&gt;
&lt;p&gt;Before now, PgDD was a &lt;a href="/2019/11/pgdd-now-postgresql-extension"&gt;raw SQL extension&lt;/a&gt;, with that version being an evolution from prior iterations.
Shortly after I converted PgDD to a raw SQL extension I wanted it to do more,
specifically related to supporting newer features such as
&lt;a href="/2019/12/postgres12-generated-columns-postgis"&gt;generated columns&lt;/a&gt;
and
&lt;a href="/2021/02/postgres-postgis-why-partition-openstreetmap"&gt;native partitioning&lt;/a&gt;.
Supporting new features in new versions of Postgres is a good idea, but I couldn't
drop support for older versions at that time either.
Using generated columns as an example, the feature was added in Postgres 12 and
came along with an update to the &lt;a href="https://www.postgresql.org/docs/current/catalog-pg-attribute.html"&gt;&lt;code&gt;pg_catalog.pg_attribute&lt;/code&gt;&lt;/a&gt; system
catalog.  In Pg12 and newer, &lt;code&gt;pg_attribute&lt;/code&gt;
has a column named &lt;code&gt;attgenerated&lt;/code&gt; while earlier versions of Postgres do not have
that column.&lt;/p&gt;
</description><pubDate>Fri, 08 Oct 2021 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2021/10/pgdd-extension-using-pgx-rust</guid></item><item><title>Timescale, Compression and OpenStreetMap Tags</title><link>https://blog.rustprooflabs.com/2021/08/timescale-compression-openstreetmap-tags</link><description>&lt;p&gt;This post captures my initial exploration with the Timescale DB extension in Postgres.
I have watched Timescale with interest for quite some time but had not really
experimented with it before now. I am considering  Timescale as another
solid option for improving my long-term storage of OpenStreetMap data snapshots.
Naturally, I am using PostGIS enabled databases filled with OpenStreetMap data.&lt;/p&gt;
&lt;p&gt;I started looking at restructuring our OpenStreetMap data with my post
&lt;a href="/2021/02/postgres-postgis-why-partition-openstreetmap"&gt;Why Partition OpenStreetMap data?&lt;/a&gt;
That post has an overview of the historic use case I need to support.
While my &lt;a href="/2021/02/postgres-partition-openstreetmap-road-v1-review"&gt;1st attempt at declarative partitioning&lt;/a&gt;
ran into a snag,
my &lt;a href="/2021/02/postgres-partition-openstreetmap-road-v2-review"&gt;2nd attempt&lt;/a&gt;
worked rather well.  This post looks beyond my initial requirements for the project
and establishes additional benefits from adding Timescale into our databases.&lt;/p&gt;
&lt;h2&gt;Timescale benefits&lt;/h2&gt;
&lt;p&gt;There are two main reasons I am looking into Timescale as an option over 
Postgres' built-in declarative partitioning:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No need to manually create partitions&lt;/li&gt;
&lt;li&gt;Compression is tempting&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;New partitions with Postgres' declarative partitioning must be created manually.
The syntax isn't terribly tricky and the process can be automated, but it still
exists therefore it still needs to be managed.
When using Timescale's hypertables new partitions are handled behind
the scenes without my direct intervention.
The other temptation from Timescale is their columnar-style compression
on row-based data.  In standard Postgres, the only time compression kicks in is
at the row level when a single row will exceed a specified size (default 2kb).
See my post on &lt;a href="/2020/07/postgres-storing-large-text"&gt;large text data in Postgres&lt;/a&gt;
that discusses compression in Postgres.
Timescale has been
&lt;a href="https://blog.timescale.com/blog/building-columnar-compression-in-a-row-oriented-database/"&gt;writing&lt;/a&gt;
about
&lt;a href="https://blog.timescale.com/blog/time-series-compression-algorithms-explained/"&gt;their compression&lt;/a&gt;
so I figured it was time to give it a go.
While compression wasn't one of the
original goals I &lt;a href="/2021/02/postgres-postgis-why-partition-openstreetmap"&gt;had outlined&lt;/a&gt;...
it would be nice!!&lt;/p&gt;
</description><pubDate>Fri, 20 Aug 2021 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2021/08/timescale-compression-openstreetmap-tags</guid></item><item><title>Better OpenStreetMap places in PostGIS</title><link>https://blog.rustprooflabs.com/2021/01/pgosm-flex-improved-openstreetmap-places-postgis</link><description>&lt;p&gt;Data quality is important.  This post continues exploring the
improved quality of OpenStreetMap data loaded to Postgres/PostGIS
&lt;a href="https://github.com/rustprooflabs/pgosm-flex"&gt;via PgOSM-Flex&lt;/a&gt;.
These improvements are enabled by the
&lt;a href="https://osm2pgsql.org/doc/manual.html#the-flex-output"&gt;new flex output of osm2pgsql&lt;/a&gt;,
making it easier to understand and consume OpenStreetMap data for
analytic purposes.&lt;/p&gt;
&lt;p&gt;I &lt;a href="/2020/12/osm2gpsql-flex-output-to-postgis"&gt;started exploring the Flex output&lt;/a&gt;
a few weeks ago,
the &lt;a href="/2021/01/postgis-openstreetmap-flex-structure"&gt;post before this one used PgOSM-Flex v0.0.3&lt;/a&gt;.
This post uses PgOSM-Flex v0.0.7 and highlights a few cool improvements
by exploring the OSM place data.  Some of the improvements made of the past
few weeks were ideas brought over from the legacy PgOSM project.
Other improvements were spurred by questions and conversations with the
community, such as the
&lt;a href="https://github.com/rustprooflabs/pgosm-flex/issues/37"&gt;nested admin polygons&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Improved places&lt;/h2&gt;
&lt;p&gt;This post focuses on the &lt;code&gt;osm.place_polygon&lt;/code&gt; data that stores things like
city, county and Country boundaries, along with neighborhoods and other details.
The the format of place data has a number of improvements covered in this post:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Consolidated name&lt;/li&gt;
&lt;li&gt;Remove duplication between relation/member polygons&lt;/li&gt;
&lt;li&gt;Boundary hierarchy&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The data loaded for this post is the &lt;a href="https://download.geofabrik.de/north-america/us-west.html"&gt;U.S. West sub-region&lt;/a&gt; from
Geofabrik.  It was loaded using the &lt;code&gt;run-all.lua&lt;/code&gt; and &lt;code&gt;run-all.sql&lt;/code&gt; scripts
in
&lt;a href="https://github.com/rustprooflabs/pgosm-flex"&gt;PgOSM-Flex&lt;/a&gt;.&lt;/p&gt;
</description><pubDate>Sat, 23 Jan 2021 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2021/01/pgosm-flex-improved-openstreetmap-places-postgis</guid></item><item><title>Partition OpenStreetMap data in PostGIS</title><link>https://blog.rustprooflabs.com/2021/02/postgres-postgis-partition-openstreetmap-road</link><description>&lt;p&gt;This post continues my quest to explore Postgres native 
partitioning and determine if it is a good fit for my OpenStreetMap data in PostGIS.
I show how I am planning to implement a partitioning
scheme in a way that &lt;strong&gt;a)&lt;/strong&gt; works well for my use case, and &lt;strong&gt;b)&lt;/strong&gt; is easy
to implement and maintain.&lt;br /&gt;
My previous post covered why
&lt;a href="/2021/02/postgres-postgis-why-partition-openstreetmap"&gt;I think partitioning will be a benefit&lt;/a&gt;
in our databases.&lt;/p&gt;
&lt;p&gt;The following steps are the result of a few iterations of ideas,
including &lt;a href="https://github.com/openstreetmap/osm2pgsql/discussions/1415"&gt;asking the osm2pgsql team&lt;/a&gt;
about one idea I had. Ultimately, I think it is good
that osm2pgsql will not support the idea I had asked about there. It forced me
to rethink my approach and end up at a better solution.
The reality is that partitioning only make sense
if the partitioning scheme supports the end use, and end uses are
quite varied. Trying to automate
partitioning directly in the PgOSM-Flex project would have greatly increased
costs of maintaining that project, and likely wasted a ton of time.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The &lt;a href="/2021/02/postgres-partition-openstreetmap-road-v1-review"&gt;post after this one&lt;/a&gt;
shows that the plan outlined in this post is not perfect, though it shows great promise.
There will be at least one more post
to outline how everything all work out!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Prepare for partitioning&lt;/h2&gt;
&lt;p&gt;I am using OpenStreetMap data loaded by
&lt;a href="https://github.com/rustprooflabs/pgosm-flex"&gt;PgOSM-Flex&lt;/a&gt;,
testing with the &lt;code&gt;osm.road_line&lt;/code&gt; table
(see more &lt;a href="/category/pgosm-flex"&gt;posts on PgOSM-Flex&lt;/a&gt;). Eventually I plan
to partition a few tables from the imported data, but to start with I am working
only with the roads.</description><pubDate>Tue, 16 Feb 2021 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2021/02/postgres-postgis-partition-openstreetmap-road</guid></item><item><title>First Review of Partitioning OpenStreetMap</title><link>https://blog.rustprooflabs.com/2021/02/postgres-partition-openstreetmap-road-v1-review</link><description>&lt;p&gt;My previous two posts set the stage to evaluate declarative Postgres partitioning
for OpenStreetMap data.
This post outlines what I found when I tested my plan and outlines my next steps.
The goal with this series is to determine if partitioning
is a path worth going down, or if the additional complexity outweighs any benefits.
The first post on partitioning outlined &lt;a href="/2021/02/postgres-postgis-why-partition-openstreetmap"&gt;my use case and &lt;strong&gt;why&lt;/strong&gt; I thought&lt;/a&gt;
partitioning would be a potential benefit. The maintenance aspects of
partitioning are my #1 hope for improvement, with easy and fast loading and removal
of entire data sets being a big deal for me.&lt;/p&gt;
&lt;p&gt;The second post
&lt;a href="/2021/02/postgres-postgis-partition-openstreetmap-road"&gt;detailed my approach to partitioning&lt;/a&gt;
to allow me to partition based on date and region. In that post I
even bragged that a clever workaround was a suitable solution.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"No big deal, creating the &lt;code&gt;osmp.pgosm_flex_partition&lt;/code&gt; table gives each &lt;code&gt;osm_date&lt;/code&gt; + &lt;code&gt;region&lt;/code&gt; a single ID to use to define list partitions."
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-- &lt;em&gt;Arrogant Me&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Read on to see where that assumption fell apart and my planned next steps.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I was hoping to have made a "Go / No-Go" decision by this point... I am currently
at a solid "Probably!"&lt;/p&gt;
&lt;h2&gt;Load data&lt;/h2&gt;
&lt;p&gt;For testing I simulated Colorado data being loaded once per
month on the 1st of each month and North America once per year on January 1.
This was conceptually easier to implement and test than trying to capture
exactly what I described in my initial post.
This approach resulted in 17 snapshots of OpenStreetMap being loaded,
15 with Colorado and two with North America.
I loaded this data twice, once using the planned partitioned setup and
the other using a simple stacked table to compare performance against.&lt;/p&gt;
</description><pubDate>Sun, 21 Feb 2021 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2021/02/postgres-partition-openstreetmap-road-v1-review</guid></item><item><title>Identify OpenStreetMap changes with Postgres</title><link>https://blog.rustprooflabs.com/2021/08/postgres-openstreetmap-changes-over-time-json</link><description>&lt;p&gt;The data in the main OpenStreetMap database is constantly changing.
Folks around the world are almost certainly saving changes via
&lt;a href="https://wiki.openstreetmap.org/wiki/JOSM"&gt;JOSM&lt;/a&gt;, &lt;a href="https://wiki.openstreetmap.org/wiki/ID"&gt;iD&lt;/a&gt;,
and other editors as you read these words.
With change constantly occurring in the data, it is often desirable
to have an idea of what has actually changed in the data.
This post explores one approach to tracking changes to
the &lt;a href="https://wiki.openstreetmap.org/wiki/Tags"&gt;tags&lt;/a&gt; attribute
data once it has been loaded to Postgres.&lt;/p&gt;
&lt;p&gt;The topic of this post surfaced while I was working on refreshing
a project involving travel times (routing).  In the process I noticed a
few instances where the analysis had shifted significantly.
My first hunch was that entire segments of road had been
added or removed, but that was not
the cause.  It became apparent that tags in the area had been
improved. It was easy to specifically point to the value associated
with the &lt;code&gt;highway&lt;/code&gt; key but I also knew there were other changes
happening, I just wasn't sure what all was involved and at what scale.&lt;/p&gt;
&lt;h2&gt;Calculate tag hash&lt;/h2&gt;
&lt;p&gt;The database I am working in has five (5) Colorado
snapshots loaded spanning back to 2018.  The tags data is loaded
to a table named &lt;code&gt;osmts.tags&lt;/code&gt;, read my post
&lt;a href="/2021/08/timescale-compression-openstreetmap-tags"&gt;Timescale, Compression and OpenStreetMap Tags&lt;/a&gt;
for how this table was created.  The &lt;code&gt;tags&lt;/code&gt; table has one row for
every OpenStreetMap feature and stores the full key/value attribute data
in a JSONB column (&lt;code&gt;osmts.tags.tags&lt;/code&gt;).
A relatively simple way to detecting change in data is to
calculate the hash for each feature's key/value data.  Comparing
hashes for any change will identify rows that had changes to their
attribute data.&lt;/p&gt;
</description><pubDate>Mon, 30 Aug 2021 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2021/08/postgres-openstreetmap-changes-over-time-json</guid></item><item><title>Psycopg3 Initial Review</title><link>https://blog.rustprooflabs.com/2021/09/psycopg3-initial-review</link><description>&lt;p&gt;If you use Postgres and Python together you are almost certainly
familiar with psycopg2.
Daniele Varrazzo has been the maintainer of the psycopg project for
many years.
In 2020 Daniele started working full-time on creating psycopg3,
the successor to psycopg2. Recently, the
&lt;a href="https://www.psycopg.org/articles/2021/08/30/psycopg-30-beta1-released/"&gt;Beta 1 release of psycopg3&lt;/a&gt;
was made &lt;a href="https://www.psycopg.org/psycopg3/docs/basic/install.html"&gt;available via PyPI install&lt;/a&gt;.
This post highlights two pieces of happy news with psycopg3:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Migration is easy&lt;/li&gt;
&lt;li&gt;The connection pool rocks&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As the first section shows, migration from psycopg2 to psycopg3 is quite easy.
The majority of this post is dedicated to examining pyscopg3's connection pool
and the difference this feature can make to your application's performance.&lt;/p&gt;
&lt;h2&gt;Migration&lt;/h2&gt;
&lt;p&gt;Easy migration is an important feature to encourage developers to upgrade.
It is frustrating when a "simple upgrade" turns into a cascade
of error after error throughout your application.
Luckily for us, psycopg3 got this part right!  In the past week I fully migrated
two projects to psycopg3 and started migrating two more projects. So far
the friction has been very low and confined to edge case uses.&lt;/p&gt;
&lt;p&gt;The following example shows a simplified example of how my projects have
used &lt;code&gt;psycopg2&lt;/code&gt;.&lt;/p&gt;
</description><pubDate>Tue, 07 Sep 2021 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2021/09/psycopg3-initial-review</guid></item><item><title>Find missing crossings in OpenStreetMap with PostGIS</title><link>https://blog.rustprooflabs.com/2021/11/postgis-find-openstreetmap-missing-crossing</link><description>&lt;p&gt;The &lt;a href="https://www.gislounge.com/november-map-challenge/"&gt;#30DayMapChallenge&lt;/a&gt;
is going on again this November.  Each day of the month has a different theme
for that day's map challenge.  These challenges do not have a requirement
for technology, so naturally I am using
&lt;a href="https://www.openstreetmap.org/about"&gt;OpenStreetMap data&lt;/a&gt; stored in
&lt;a href="https://postgis.net/"&gt;PostGIS&lt;/a&gt; with
&lt;a href="https://www.qgis.org/"&gt;QGIS&lt;/a&gt; for
the visualization component.&lt;/p&gt;
&lt;p&gt;The challenge for Day 5 was an OpenStreetMap data challenge.
I decided to find and visualize missing
&lt;a href="https://wiki.openstreetmap.org/wiki/Key:crossing"&gt;crossing tags&lt;/a&gt;.
Crossing tags are added to the node (point) where a pedestrian
highway (e.g. &lt;code&gt;highway=footway&lt;/code&gt;) intersects a motorized highway
(e.g. &lt;code&gt;highway=tertiary&lt;/code&gt;).
This post explains how I used PostGIS and OpenStreetMap data to
find intersections missing a dedicated crossing tag.&lt;/p&gt;
&lt;p&gt;Without further ado, here was my submission for Day 5.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Map of the Denver, Colorado metro area with a shaded hex grid overlay. Title reads &amp;quot;% of Footway Intersections missing Crossing&amp;quot;.  Subtitles read &amp;quot;Denver Metro area, November 2021&amp;quot; and &amp;quot;#30DayMapChallenge - 2021 Day 5: OpenStreetMap&amp;quot;. The hex grid is shaded from light red to dark red (5 gradients), with only 4 of the lightest shaded areas around Denver proper.  Throughout the rest of the inner-metro area are shades 2-4 (35% through 94% missing) with most of the outer regions in the 100% or &amp;quot;no data&amp;quot; area." src="/static/images/30daychallenge-day5-missing-crossings-denver.png" /&gt;&lt;/p&gt;
</description><pubDate>Sun, 07 Nov 2021 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2021/11/postgis-find-openstreetmap-missing-crossing</guid></item><item><title>Round Two: Partitioning OpenStreetMap</title><link>https://blog.rustprooflabs.com/2021/02/postgres-partition-openstreetmap-road-v2-review</link><description>&lt;p&gt;A few weeks ago I decided to seriously consider Postgres' declarative table partitioning
for our OpenStreetMap data. Once the decision was made to investigate this option, I
&lt;a href="/2021/02/postgres-postgis-why-partition-openstreetmap"&gt;outlined our use case&lt;/a&gt;
with requirements to keep multiple versions of OpenStreetMap data over time.
That process helped draft &lt;a href="/2021/02/postgres-postgis-partition-openstreetmap-road"&gt;my initial plan&lt;/a&gt;
for how to create and manage the partitioned data.
When I put the initial code to the test
&lt;a href="/2021/02/postgres-partition-openstreetmap-road-v1-review"&gt;I found a snag and adjusted the plan&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This post shows a working example of how to partition OpenStreetMap data
loaded using &lt;a href="/2021/01/postgis-openstreetmap-flex-structure"&gt;PgOSM-Flex&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;TLDR&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Spoiler alert!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It works, I love it! I am moving forward
with the plan outlined in this post.  Some highlights from testing with
Colorado sized data:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Bulk import generates 17% less WAL&lt;/li&gt;
&lt;li&gt;Bulk delete generates 99.8% less WAL&lt;/li&gt;
&lt;li&gt;Simple aggregate query runs 75% faster&lt;/li&gt;
&lt;/ul&gt;
</description><pubDate>Fri, 26 Feb 2021 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2021/02/postgres-partition-openstreetmap-road-v2-review</guid></item><item><title>Load and query Pi-hole data from Postgres</title><link>https://blog.rustprooflabs.com/2021/02/postgresql-sqlite-fdw-pihole</link><description>&lt;p&gt;I have used &lt;a href="https://pi-hole.net/"&gt;Pi-hole&lt;/a&gt; on our local network for a
few years now.  It is running on a dedicated Raspberry Pi 3B attached
to the router (Netgear Nighthawk) to provide fast local DNS/DCHP while
blocking ads at the network level.
The built-in Pi-hole web interface allows for some basic querying/reporting
of the collected data, but it's a bit limited and quite slow as the data
grows over time. My current &lt;code&gt;pihole-FTL.db&lt;/code&gt; database is 1.4 GB and contains 12 months of data.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ls -alh /etc/pihole/pihole-FTL.db
-rw-r--r--  1 pihole pihole 1.4G Jan 31 14:04 pihole-FTL.db
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pi-hole saves its data in a few &lt;a href="https://docs.pi-hole.net/database/"&gt;SQLite databases&lt;/a&gt; with the &lt;a href="https://docs.pi-hole.net/database/ftl/"&gt;FTL database&lt;/a&gt;
(Faster Than Light) being the most interesting.
While I could try to work with the data directly in SQLite, I strongly prefer
Postgres and decided this was a great time to give the
&lt;a href="https://github.com/pgspider/sqlite_fdw"&gt;pgspider/sqlite_fdw&lt;/a&gt; extension
a try.  This post goes over the steps I took to bring Pi-hole data into
Postgres from its sqlite data source.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;See &lt;a href="/2020/03/postgresql-fdw-remote-file"&gt;my previous post on using &lt;code&gt;file_fdw&lt;/code&gt;&lt;/a&gt; for more about Postgres' Foreign Data Wrappers.&lt;/p&gt;
&lt;/blockquote&gt;
</description><pubDate>Mon, 01 Feb 2021 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2021/02/postgresql-sqlite-fdw-pihole</guid></item><item><title>Postgres Permissions and Materialized Views</title><link>https://blog.rustprooflabs.com/2021/07/postgres-permission-mat-view</link><description>&lt;p&gt;Materialized views in Postgres are a handy way to persist the result
of a query to disk. This is helpful when the underlying query
is expensive and slow yet high performance &lt;code&gt;SELECT&lt;/code&gt; queries are required.
When using &lt;a href="https://www.postgresql.org/docs/current/rules-materializedviews.html"&gt;materialized views&lt;/a&gt;
they need to be explicitly refreshed to show changes to the underlying
table. This is done through the &lt;code&gt;REFRESH MATERIALIZED VIEW &amp;lt;name&amp;gt;;&lt;/code&gt;
syntax.&lt;/p&gt;
&lt;p&gt;Keeping materialized views regularly refreshed is often a delegated
to a cron job on a schedule. There is also often a need for database
users to manually refresh the data on demand. At this point many
users stub their toe on permissions because
&lt;a href="https://www.postgresql.org/docs/current/sql-refreshmaterializedview.html"&gt;refreshing a materialized view&lt;/a&gt;
can only be done by the owner of the materialized view.
This post uses a simple example to illustrate how to delegate refresh
permissions to other Postgres roles.&lt;/p&gt;
</description><pubDate>Mon, 05 Jul 2021 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2021/07/postgres-permission-mat-view</guid></item><item><title>Permissions required for PostGIS</title><link>https://blog.rustprooflabs.com/2021/12/postgis-permissions-required</link><description>&lt;p&gt;&lt;a href="https://postgis.net/"&gt;PostGIS&lt;/a&gt; is a widely popular spatial database extension for Postgres.
It's also one of my favorite tools!
A recent discussion on the &lt;a href="https://discord.gg/EFqQfBx7av"&gt;People, Postgres, Data&lt;/a&gt;
Discord server highlighted that the permissions required for various PostGIS
operations were not clearly explained in the PostGIS documentation.
As it turned out, I didn't know exactly what was required either.
The basic &lt;a href="https://postgis.net/install/"&gt;PostGIS install page&lt;/a&gt; provides resources
for installing the binary on the server and the basic &lt;code&gt;CREATE EXTENSION&lt;/code&gt; commands,
but does not explain permissions required.&lt;/p&gt;
&lt;p&gt;This post explores the permissions required for three types of PostGIS interactions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Install/Create PostGIS&lt;/li&gt;
&lt;li&gt;Use PostGIS&lt;/li&gt;
&lt;li&gt;Load data from &lt;code&gt;pg_dump&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Database and Users&lt;/h2&gt;
&lt;p&gt;I am using Postgres installed on my laptop for these tests, Postgres 13.5 and
PostGIS 3.1.
I created an empty database named &lt;code&gt;postgis_perms&lt;/code&gt; and check the &lt;code&gt;\du&lt;/code&gt;
slash command in psql to see the current roles.  This instance has my
my &lt;code&gt;ryanlambert&lt;/code&gt; role, a superuser, and the default &lt;code&gt;postgres&lt;/code&gt; role.
The &lt;code&gt;postgres&lt;/code&gt; role is not used in this post outside of this example.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;([local] 🐘) ryanlambert@postgis_perms=# \du
                                     List of roles
┌─────────────┬────────────────────────────────────────────────────────────┬───────────┐
│  Role name  │                         Attributes                         │ Member of │
╞═════════════╪════════════════════════════════════════════════════════════╪═══════════╡
│ postgres    │ Superuser, Create role, Create DB, Replication, Bypass RLS │ {}        │
│ ryanlambert │ Superuser, Create role, Create DB                          │ {}        │
└─────────────┴────────────────────────────────────────────────────────────┴───────────┘
&lt;/code&gt;&lt;/pre&gt;
</description><pubDate>Wed, 01 Dec 2021 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2021/12/postgis-permissions-required</guid></item><item><title>OpenStreetMap to PostGIS is getting lighter</title><link>https://blog.rustprooflabs.com/2021/05/osm2pgsql-reduced-ram-load-to-postgis</link><description>&lt;p&gt;If you have ever wanted OpenStreetMap data in Postgres/PostGIS, you
are probably familiar with the
&lt;a href="https://osm2pgsql.org/"&gt;osm2pgsql&lt;/a&gt; tool.
Lately I have been writing about the osm2pgsql developments with the
&lt;a href="/2020/12/osm2gpsql-flex-output-to-postgis"&gt;new Flex output&lt;/a&gt; and
how it is enabling &lt;a href="/2021/01/postgis-openstreetmap-flex-structure"&gt;improved&lt;/a&gt;
data &lt;a href="/2021/01/pgosm-flex-improved-openstreetmap-places-postgis"&gt;quality&lt;/a&gt;.
This post changes focus away from the flex output and examines the 
performance of the osm2pgsql load itself.&lt;/p&gt;
&lt;p&gt;One challenge with osm2pgsql over the years has been generic
recommendations have been difficult to make. The safest recommendation
for nearly any combination of hardware and source data size was
to use &lt;code&gt;osm2pgsql --slim --drop&lt;/code&gt; to put most of the intermediate data
into Postgres instead of relying directly on RAM, which it needed a lot of.
This choice has offsetting costs of putting all that data into Postgres (only to be deleted) in terms of disk usage and I/O performance.&lt;/p&gt;
&lt;p&gt;A few days ago, a
&lt;a href="https://github.com/openstreetmap/osm2pgsql/pull/1461"&gt;pull request&lt;/a&gt; from Jochen Topf to create a new RAM middle caught my eye.
The text that piqued my interest (emphasis mine):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When not using two-stage processing the memory requirements are much much smaller than with the old ram middle. Rule of thumb is, &lt;strong&gt;you'll need about 1GB plus 2.5 times the size of the PBF file as memory.&lt;/strong&gt; This makes it possible to import even continent-sized data on reasonably-sized machines.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Wait... what?!  Is this for real??&lt;/p&gt;
</description><pubDate>Sat, 01 May 2021 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2021/05/osm2pgsql-reduced-ram-load-to-postgis</guid></item><item><title>Using Query ID in Postgres 14</title><link>https://blog.rustprooflabs.com/2021/10/postgres-14-query-id</link><description>&lt;p&gt;&lt;a href="https://www.postgresql.org/docs/14/release-14.html"&gt;Postgres 14 was released&lt;/a&gt;
on September 30, 2021.  With a new major version comes new features
to explore!
This post takes a look at the unique query id option
&lt;a href="https://www.postgresql.org/docs/14/runtime-config-statistics.html#GUC-COMPUTE-QUERY-ID"&gt;enabled with &lt;code&gt;compute_query_id&lt;/code&gt;&lt;/a&gt;
in &lt;code&gt;postgresql.conf&lt;/code&gt;.
This particular backend improvement, included with Postgres 14, is one I am
excited about because it makes investigating and
monitoring query related performance easier.
This post covers how to enable the new feature and explores how it can be used
in real life performance tuning.&lt;/p&gt;
&lt;h2&gt;Enable query id&lt;/h2&gt;
&lt;p&gt;For testing I created a new instance with Postgres 14 installed
and edited the &lt;code&gt;postgresql.conf&lt;/code&gt; file to change a few configuration options
related to the query id.
I set &lt;code&gt;compute_query_id&lt;/code&gt; to &lt;code&gt;on&lt;/code&gt; instead of &lt;code&gt;auto&lt;/code&gt;
and to allow the &lt;code&gt;pg_stat_statements&lt;/code&gt; extension to be loaded.
Additionally, I turn on &lt;code&gt;log_duration&lt;/code&gt;, set &lt;code&gt;log_statement&lt;/code&gt; to &lt;code&gt;all&lt;/code&gt;
and update &lt;a href="https://www.postgresql.org/docs/14/runtime-config-logging.html#GUC-LOG-LINE-PREFIX"&gt;&lt;code&gt;log_line_prefix&lt;/code&gt; to include&lt;/a&gt;
&lt;code&gt;query_id=%Q&lt;/code&gt;,&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;compute_query_id = on
shared_preload_libraries = 'pg_stat_statements'

log_duration = on
log_statement = 'all'
log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h,query_id=%Q '
&lt;/code&gt;&lt;/pre&gt;
</description><pubDate>Fri, 15 Oct 2021 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2021/10/postgres-14-query-id</guid></item><item><title>Improved OpenStreetMap data structure in PostGIS</title><link>https://blog.rustprooflabs.com/2021/01/postgis-openstreetmap-flex-structure</link><description>&lt;p&gt;It was nearly a decade ago when I first loaded OpenStreetMap data to PostGIS.
Over the years my fingers have typed &lt;code&gt;osm2pgsql --slim --drop ...&lt;/code&gt; countless times
and I do not see an end to that trend anytime soon.
One thing that is changing is that getting &lt;strong&gt;high quality&lt;/strong&gt; OpenStreetMap data into 
PostGIS is easier than ever!
This improvement in data quality is made possible by the new Flex output available in osm2pgsql 1.4.0,
I &lt;a href="/2020/12/osm2gpsql-flex-output-to-postgis"&gt;wrote about my initial impressions of the Flex output&lt;/a&gt; a few weeks ago.&lt;/p&gt;
&lt;p&gt;This post looks at how I am starting to use osm2pgsql's Flex output to provide a 
standardized and sanitized OpenStreetMap data set in Postgres/PostGIS.
No longer is osm2pgsql limited to loading data to the 3-table structure
(&lt;code&gt;planet_osm_point&lt;/code&gt;, &lt;code&gt;planet_osm_line&lt;/code&gt; and &lt;code&gt;planet_osm_polygon&lt;/code&gt;)
so I am eagerly converting to the Flex output and taking advantage of these changes!
It is also easier than ever to create customized mix-and-match data loads
for customized needs of specific projects.&lt;/p&gt;
</description><pubDate>Sun, 03 Jan 2021 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2021/01/postgis-openstreetmap-flex-structure</guid></item><item><title>Use BIGINT in Postgres</title><link>https://blog.rustprooflabs.com/2021/06/postgres-bigint-by-default</link><description>&lt;p&gt;This post examines a common database design decision
involving the choice of using &lt;code&gt;BIGINT&lt;/code&gt; versus &lt;code&gt;INT&lt;/code&gt; data types.
You may already know that the &lt;code&gt;BIGINT&lt;/code&gt; data type uses
twice the storage on disk (8 bytes per value) compared to
the &lt;code&gt;INT&lt;/code&gt; data type (4 bytes per value).
Knowing this, a common
decision is to use &lt;code&gt;INT&lt;/code&gt; wherever possible, only resorting to using
&lt;code&gt;BIGINT&lt;/code&gt; when it was obvious&amp;#42;
that the column will be storing
values greater than 2.147 Billion (the
&lt;a href="https://www.postgresql.org/docs/current/datatype-numeric.html"&gt;max of &lt;code&gt;INT&lt;/code&gt;&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;That's what I did too, until 2-3 years ago!
I started changing my default mindset to using &lt;code&gt;BIGINT&lt;/code&gt; over &lt;code&gt;INT&lt;/code&gt;,
reversing my long-held habit.
This post explains why I default to using &lt;code&gt;BIGINT&lt;/code&gt;
and examine the performance impacts of the decision.&lt;/p&gt;
&lt;h2&gt;TLDR;&lt;/h2&gt;
&lt;p&gt;As I conclude at the end:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The tests I ran here show that a production-scale database with properly sized hardware can handle that slight overhead with no problem.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Why default to &lt;code&gt;BIGINT&lt;/code&gt;?&lt;/h2&gt;
&lt;p&gt;The main reason to default to &lt;code&gt;BIGINT&lt;/code&gt; is to avoid
&lt;code&gt;INT&lt;/code&gt; to &lt;code&gt;BIGINT&lt;/code&gt; migrations. The need to do an &lt;code&gt;INT&lt;/code&gt; 
to &lt;code&gt;BIGINT&lt;/code&gt; migration comes up at the
least opportune time and the task is time consuming.
This type of migration typically involves at least one column used
as a &lt;code&gt;PRIMARY KEY&lt;/code&gt; and that is often used elsewhere as a &lt;code&gt;FOREIGN KEY&lt;/code&gt;
on other table(s) that must also be migrated.&lt;/p&gt;
&lt;p&gt;In the spirit of defensive database design, &lt;code&gt;BIGINT&lt;/code&gt;
is the safest choice. Remember the &lt;strong&gt;&amp;#42;obvious&lt;/strong&gt; part mentioned
above? Planning and estimating is a difficult topic and
people (myself included) get it wrong all the time!
Yes, there is overhead for using &lt;code&gt;BIGINT&lt;/code&gt;,
but I believe the overhead associated with the extra 4 bytes 
is trivial for the majority of production databases.&lt;/p&gt;
</description><pubDate>Sat, 05 Jun 2021 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2021/06/postgres-bigint-by-default</guid></item><item><title>Why Partition OpenStreetMap data?</title><link>https://blog.rustprooflabs.com/2021/02/postgres-postgis-why-partition-openstreetmap</link><description>&lt;p&gt;This post covers the first part of my path in considering native
Postgres partitioning and how it might be helpful to my work with OpenStreetMap data in PostGIS.
Partitioning tables in Postgres can have significant
benefits when working with larger data sets, and OpenStreetMap
data as a whole is generally considered a large data set.
The post following this one will outline the steps I am taking to implement
partitioning with data loaded by &lt;a href="https://github.com/rustprooflabs/pgosm-flex"&gt;PgOSM-Flex&lt;/a&gt;. A third post is planned to dive
into the impacts on performance this change has.&lt;/p&gt;
&lt;p&gt;Table partitioning is not an architecture that should be implemented
casually without planning and good reason.
The consequences of a poorly planned and implemented partitioning scheme can be severe.  This is why it is worth the extra time to
plan, evaluate and test this option before making any lasting implementation
decisions. This post starts by examining the work flow I have
used with OpenStreetMap data, challenges with my legacy approach,
and highlights where I think Postgres partitioning can provide serious
improvement. My &lt;a href="/2021/02/postgres-postgis-partition-openstreetmap-road"&gt;next post&lt;/a&gt;
shows how I am approaching the task of partitioning OpenStreetMap data.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;At the time of writing this post I have &lt;strong&gt;not decided&lt;/strong&gt; if this is a path I will continue down for production use. I have not started testing and collecting data for the 3rd post. I will likely make the "Go / No-Go" decision while I am collecting data for the performance related post.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;OpenStreetMap for Analytics&lt;/h2&gt;
&lt;p&gt;The main way I use OpenStreetMap data is within analytics style projects.
Routing, travel times, watersheds, urban growth, and land usage are all
easily within scope for OpenStreetMap data in PostGIS.&lt;/p&gt;
</description><pubDate>Sun, 14 Feb 2021 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2021/02/postgres-postgis-why-partition-openstreetmap</guid></item><item><title>Using Uber's H3 hex grid in PostGIS</title><link>https://blog.rustprooflabs.com/2022/04/postgis-h3-intro</link><description>&lt;p&gt;This post explores using the &lt;a href="https://eng.uber.com/h3/"&gt;H3 hex grid system&lt;/a&gt;
within PostGIS. H3 was developed by Uber and has some cool benefits
over the PostGIS native &lt;code&gt;ST_HexagonGrid()&lt;/code&gt; function used
in my post &lt;a href="/2021/11/postgis-find-openstreetmap-missing-crossing"&gt;Find missing crossings in OpenStreetMap with PostGIS&lt;/a&gt;.
The hex grid built-in to PostGIS is great for one-off projects covering a specific region,
though it has shortcomings for larger scale consistency.
On the other hand, the H3 grid is a globally defined grid that scales up and down
through resolutions neatly. For more details, read
&lt;a href="https://eng.uber.com/h3/"&gt;Uber's description&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This post used the H3 v3 extension. See &lt;a href="/2023/05/postgis-h3-v4-refresh"&gt;Using v4 of the Postgres H3 extension&lt;/a&gt; for usage in the latest version.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This post works through a few of the functions available in the H3 extension
and how they can be used for spatial aggregation in an analysis. One additional
focus is how to generate a table of H3 hexagons for a given resolution.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note:  This post does not focus on using H3 for the best performance.  See my post &lt;a href="/2022/06/h3-indexes-on-postgis-data"&gt;H3 indexes for performance with PostGIS data&lt;/a&gt; for a look into high performance spatial searches with H3.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Install H3 in Postgres&lt;/h2&gt;
&lt;p&gt;The H3 library is available to PostGIS as a Postgres extension. I am using
the &lt;a href="https://github.com/bytesandbrains/h3-pg"&gt;bytesandbrains h3-pg project&lt;/a&gt;
available on GitHub.  The extension can be installed using
&lt;code&gt;pgxn install h3&lt;/code&gt;.  Once installed, create the H3 extension in the database.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE EXTENSION h3;
&lt;/code&gt;&lt;/pre&gt;
</description><pubDate>Sun, 24 Apr 2022 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2022/04/postgis-h3-intro</guid></item><item><title>Backups for Postgres - PGSQL Phriday #002</title><link>https://blog.rustprooflabs.com/2022/11/pgsql-phriday-002</link><description>&lt;p&gt;This blog post is for PGSQL Phriday #002.  Read
&lt;a href="https://www.softwareandbooz.com/introducing-psql-phriday/"&gt;Ryan Booz' introduction&lt;/a&gt;
from September for more details on PGSQL Phriday.
Andreas Scherbaum
&lt;a href="https://andreas.scherbaum.la/blog/archives/1122-PGSQL-Phriday-002-PostgreSQL-Backup-and-Restore.html"&gt;is this month's host&lt;/a&gt; and chose
the topic: Postgres backups!&lt;/p&gt;
&lt;p&gt;The topic reposted here:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Which tool(s) are you using, where do you store backups, how often do you do backups?
Are there any recommendations you can give the reader how to improve their backups?
Any lesser known features in your favorite backup tool?
Any new and cool features in a recently released version?&lt;/p&gt;
&lt;p&gt;Bonus question: Is pg_dump a backup tool?&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;What is a backup?&lt;/h2&gt;
&lt;p&gt;I address most of ads' questions in this post, but before we dive in
we need to define "backup."
&lt;a href="https://www.merriam-webster.com/dictionary/backup"&gt;Merriam Webster&lt;/a&gt;
has a definition for backup in the context of computers:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;backup (3): "a copy of computer data (such as a file or the contents of a hard drive)"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I'm running with this simple defintion of backup for today's post.
To frame the definition of "backup" in a non-Postgres context:  Suppose I have a "business document."  I want to make some major changes but am afraid of accidentally losing something important.  What do I do?  I copy / paste the file, change the name to include today's date, and edit away.  Did I create a backup of the original document? Sure.  In a way.
Is it the same thing as when the IT department backs up the network drive
the documents where both the original and newly modified files are saved?
Nope. Do both approaches serve their purpose?  Yes!&lt;/p&gt;
&lt;p&gt;Database backups are similar.  There isn't a one-size-fits-all solution.&lt;/p&gt;
</description><pubDate>Fri, 04 Nov 2022 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2022/11/pgsql-phriday-002</guid></item><item><title>Routing with Lines through Polygons</title><link>https://blog.rustprooflabs.com/2022/10/pgrouting-lines-through-polygons</link><description>&lt;p&gt;One of my favorite layers to route with &lt;a href="https://pgrouting.org/"&gt;pgRouting&lt;/a&gt; is the water layer.  I am interested
in where water comes from, where it goes, where runoff happens,
and how urban development interacts with this powerful force
of nature. The OpenStreetMap water layer, however,
presents a challenge when routing with PostGIS and pgRouting: Polygons.&lt;/p&gt;
&lt;p&gt;Why are polygons a challenge?  A routing network using pgRouting is built
from &lt;strong&gt;lines&lt;/strong&gt; (edges).
Now, to state the obvious: polygons are not lines.&lt;/p&gt;
&lt;p&gt;Real world waterway networks are made up of both lines and polygons.
Rivers, streams, and drainage routes are predominately (but not exclusively!)
mapped using lines. These lines feed into and out of ponds, lakes, and reservoirs. 
The following animation shows how much impact the water polygons
can have on a waterway network... some very important paths simply
disappear when they are excluded.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Animated image showing an area northwest of Denver, Colorado with a few large reservoirs (polygons) connected by waterways (lines).  The animation shows the impact of taking these large polygons out of the routing equation, many important route options disappear." src="/static/images/water-polygons-are-important-for-routing.gif" /&gt;&lt;/p&gt;
&lt;p&gt;To make the full water network route-able we need to create a combined
line layer.  The combined line layer will include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Initial &lt;code&gt;osm.water_line&lt;/code&gt; inputs&lt;/li&gt;
&lt;li&gt;Medial axis lines from &lt;code&gt;osm.water_polygon&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Lines to connect initial inputs to medial axis&lt;/li&gt;
&lt;/ul&gt;
</description><pubDate>Sun, 23 Oct 2022 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2022/10/pgrouting-lines-through-polygons</guid></item><item><title>Postgres 15 Configuration Changes</title><link>https://blog.rustprooflabs.com/2022/10/postgres-15-config-changes</link><description>&lt;p&gt;A few years ago around the time PostgreSQL 12 was released, I
&lt;a href="/2019/12/exploring-pgconfig-comparison-tool"&gt;created a tool&lt;/a&gt; to help
identify the changes to &lt;code&gt;postgresql.conf&lt;/code&gt;. The pgConfig tool has helped me become
(and stay) aware of important changes to Postgres configuration as I work with 
various major version upgrades.
Now that &lt;a href="https://www.postgresql.org/about/news/postgresql-15-released-2526/"&gt;Postgres 15&lt;/a&gt;
is available,
&lt;a href="https://pgconfig.rustprooflabs.com/param/change/14/15"&gt;pgConfig is updated&lt;/a&gt; 
with the latest
configuration.
This post provides a quick look at changes in the Postgres 15
version of the &lt;code&gt;postgresql.conf&lt;/code&gt; options.&lt;/p&gt;
&lt;h2&gt;Summary of changes&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;postgresql.conf&lt;/code&gt; for Postgres 15 has 6 new items,
3 changed items and 1 removed item. Visit the
&lt;a href="https://pgconfig.rustprooflabs.com/param/change/14/15"&gt;pgConfig site&lt;/a&gt;
to see the full list of changes.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Screenshot showing the summary of changes in configuration from Postgres 14 to Postgres 15.  6 new parameters, 3 updated defaults, and 1 removed." src="/static/images/pgconfig-changes-pg14-to-pg15.png" /&gt;&lt;/p&gt;
</description><pubDate>Sun, 16 Oct 2022 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2022/10/postgres-15-config-changes</guid></item><item><title>Postgres 15 improves UNIQUE and NULL</title><link>https://blog.rustprooflabs.com/2022/07/postgres-15-unique-improvement-with-null</link><description>&lt;p&gt;Postgres 15 beta 2 &lt;a href="https://www.postgresql.org/about/news/postgresql-15-beta-2-released-2479/"&gt;was released&lt;/a&gt;
recently! I enjoy Beta season... reviewing and testing new features
is a fun diversion from daily tasks. This post takes a look at an improvement
to &lt;code&gt;UNIQUE&lt;/code&gt; constraints on columns with &lt;a href="https://en.wikipedia.org/wiki/Null_%28SQL%29"&gt;&lt;code&gt;NULL&lt;/code&gt; values&lt;/a&gt;. While the nuances of unique constraints are not as flashy
as &lt;a href="https://www.citusdata.com/blog/2022/05/19/speeding-up-sort-performance-in-postgres-15/"&gt;making sorts faster&lt;/a&gt; (that's exciting!),
improving the database developer's control over data quality is always a good benefit.&lt;/p&gt;
&lt;p&gt;This &lt;a href="https://www.postgresql.org/message-id/flat/84e5ee1b-387e-9a54-c326-9082674bde78%40enterprisedb.com"&gt;email chain&lt;/a&gt;
has the history behind this change.  The
&lt;a href="https://www.postgresql.org/docs/15/release-15.html"&gt;Postgres 15 release notes&lt;/a&gt;
summarize this improvement:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"Allow unique constraints and indexes to treat NULL values as not distinct (Peter Eisentraut)&lt;/p&gt;
&lt;p&gt;Previously &lt;code&gt;NULL&lt;/code&gt; values were always indexed as distinct values, but this can now be changed by creating constraints and indexes using &lt;code&gt;UNIQUE NULLS NOT DISTINCT&lt;/code&gt;."&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Two styles of &lt;code&gt;UNIQUE&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;To take a look at what this change does, we create two tables.
The &lt;code&gt;null_old_style&lt;/code&gt; table has a 2-column &lt;code&gt;UNIQUE&lt;/code&gt; constraint
on &lt;code&gt;(val1, val2)&lt;/code&gt;.  The &lt;code&gt;val2&lt;/code&gt; allows &lt;code&gt;NULL&lt;/code&gt; values.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE TABLE null_old_style
(
    id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    val1 TEXT NOT NULL,
    val2 TEXT NULL,
    CONSTRAINT uq_val1_val2
        UNIQUE (val1, val2)
);
&lt;/code&gt;&lt;/pre&gt;
</description><pubDate>Mon, 11 Jul 2022 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2022/07/postgres-15-unique-improvement-with-null</guid></item><item><title>Postgres Data Dictionary for everyone</title><link>https://blog.rustprooflabs.com/2022/01/pgdd-for-everyone</link><description>&lt;p&gt;A data dictionary is an important tool for anyone that stores and consumes
data. The &lt;a href="https://github.com/rustprooflabs/pgdd"&gt;PgDD extension&lt;/a&gt;
makes it easy to inspect and explore your data structures in Postgres.
This post shows how PgDD provides access to
current and accurate information about your databases for a variety of users:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Analysts&lt;/li&gt;
&lt;li&gt;DBAs and Developers&lt;/li&gt;
&lt;li&gt;The Business&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This data dictionary information from PgDD is made available using standard
SQL by querying a small set of views.&lt;/p&gt;
&lt;h2&gt;Background&lt;/h2&gt;
&lt;p&gt;Relational databases, including Postgres, track the majority of the information
needed for a data dictionary. This is done in the underlying
&lt;a href="https://www.postgresql.org/docs/current/catalogs-overview.html"&gt;system catalogs&lt;/a&gt;;
Postgres' system catalogs are in the &lt;code&gt;pg_catalog&lt;/code&gt; schema.
The challenge with using the system catalogs is they are not very
user friendly to query for the type of details commonly needed.
PgDD does not do anything magical, it is simply
a wrapper around the Postgres system catalogs!&lt;/p&gt;
</description><pubDate>Tue, 04 Jan 2022 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2022/01/pgdd-for-everyone</guid></item><item><title>Better OpenStreetMap data using PgOSM Flex 0.6.0</title><link>https://blog.rustprooflabs.com/2022/10/pgosm-flex-improvements-0-6-0</link><description>&lt;p&gt;In late 2020 when osm2pgsql released &lt;a href="https://osm2pgsql.org/doc/manual.html#the-flex-output"&gt;the flex output&lt;/a&gt;
I eagerly jumped on that bandwagon.
The osm2pgsql flex output enabled the type of data structure and cleanup abilities
I had always wanted from osm2pgsql. By
&lt;a href="/2021/01/pgosm-flex-improved-openstreetmap-places-postgis"&gt;January 2021&lt;/a&gt;
the &lt;a href="https://github.com/rustprooflabs/pgosm-flex"&gt;PgOSM Flex&lt;/a&gt;
project  was up and running and I was phasing out my legacy
OpenStreetMap processes.
Since then, I have written &lt;a href="/category/pgosm-flex"&gt;more than a dozen posts&lt;/a&gt;
exploring different improvements and use cases for the OpenStreetMap data
loaded via PgOSM Flex.  This post looks at a few notable improvements
to version 0.6.0 over prior versions.  The two areas of focus are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Data quality&lt;/li&gt;
&lt;li&gt;Usability&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Data quality improvements&lt;/h2&gt;
&lt;p&gt;The set of improvements that gave me the idea for this post were made
in PgOSM Flex versions 0.5.1 and 0.6.0.
&lt;a href="https://github.com/rustprooflabs/pgosm-flex/releases/tag/0.5.1"&gt;Version 0.5.1&lt;/a&gt;
took advantage of the long awaited &lt;a href="https://github.com/openstreetmap/osm2pgsql/issues/1386#issuecomment-1210376552"&gt;addition of &lt;code&gt;multilinestring&lt;/code&gt; support&lt;/a&gt;
to osm2pgsql.  Adding that feature in osm2pgsql allowed relations of lines to
be added in the same manner that
&lt;a href="/2021/01/pgosm-flex-improved-openstreetmap-places-postgis"&gt;relations of polygons&lt;/a&gt;
had used.  Without the &lt;code&gt;multilinestring&lt;/code&gt; support, relations such as
&lt;a href="https://www.openstreetmap.org/relation/13642053"&gt;13642053&lt;/a&gt;,
shown in the following screenshot, were being skipped by the PgOSM Flex import.
This improvement targeted roads, waterways, and public transport layers.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Screenshot from DBeaver showing a blue segment representing OSM relation 13642053, a roughly 33 kilometer stretch of road that had previously been excluded from data loaded by PgOSM Flex." src="/static/images/pgosm-road-line-relation-13642053.png" /&gt;&lt;/p&gt;
</description><pubDate>Tue, 04 Oct 2022 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2022/10/pgosm-flex-improvements-0-6-0</guid></item><item><title>What is the PostgreSQL community to you? - PGSQL Phriday #003</title><link>https://blog.rustprooflabs.com/2022/12/pgsql-phriday-003</link><description>&lt;p&gt;This blog post is for PGSQL Phriday #003.  Read
&lt;a href="https://www.softwareandbooz.com/introducing-psql-phriday/"&gt;Ryan Booz' introduction&lt;/a&gt;
from September for more details on PGSQL Phriday.
Pat Wright (SQL Asylum)
&lt;a href="https://sqlasylum.wordpress.com/2022/11/29/pgsql-phriday-003-what-is-the-community-to-you/"&gt;is this month's host&lt;/a&gt; and chose
the topic: &lt;strong&gt;What is the PostgreSQL community to you?&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;TLDR;&lt;/h2&gt;
&lt;p&gt;The Postgres community is helpful.&lt;/p&gt;
&lt;h2&gt;One big community with many layers&lt;/h2&gt;
&lt;p&gt;The remainder of this post explores why I say the Postgres community is helpful.
Postgres is an open source project with multiple layers and locations of community.
Membership is open, free, and no invite is needed.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Prefer having an invite? You're invited!&lt;/p&gt;
&lt;/blockquote&gt;
</description><pubDate>Fri, 02 Dec 2022 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2022/12/pgsql-phriday-003</guid></item><item><title>Book Release!  Mastering PostGIS and OpenStreetMap</title><link>https://blog.rustprooflabs.com/2022/10/announce-mastering-postgis-openstreetmap</link><description>&lt;p&gt;I'm excited to announce my book,
&lt;a href="https://postgis-osm.com" target="_blank"&gt;Mastering PostGIS and OpenStreetMap&lt;/a&gt;, is
&lt;a href="https://postgis-osm.com/buy" target="_blank"&gt;
available to purchase
&lt;/a&gt; as of October 1, 2022!
This book provides a practical guide
to introduce readers to PostGIS, OpenStreetMap data, and
spatial querying. Queries used for examples are
written against
&lt;a href="https://postgis-osm.com/data" target="_blank"&gt;real OpenStreetMap data&lt;/a&gt;
(included)
to help you learn how to navigate and explore complex spatial data.
The examples start simple and quickly progress through a
variety of clever spatial queries and powerful techniques.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Section 12.3, &lt;em&gt;Create Denver specific tables&lt;/em&gt;, is available as a
&lt;a href="https://book.postgis-osm.com/ch_pgosm/denver-area-extract.html" target='_blank'&gt;free preview&lt;/a&gt; section. The full Table of Contents is available from the free preview page.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Who is this book for?&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Mastering PostGIS and OpenStreetMap&lt;/em&gt; is for anyone that wants
to learn more about PostGIS and/or OpenStreetMap data.
The hefty Appendix helps keep new users
on track without distracting users with more experience.
The following table gives an idea of the topics covered.&lt;/p&gt;
&lt;div class="col col-md-8"&gt;
&lt;table class="table table-striped table-hover"&gt;
    &lt;tr&gt;
        &lt;th&gt;Topic&lt;/th&gt;
        &lt;th&gt;Included?&lt;/th&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Install PostGIS&lt;/td&gt;
        &lt;td&gt;✅&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Spatial SQL queries&lt;/td&gt;
        &lt;td&gt;✅&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Basics of OpenStreetMap tagging&lt;/td&gt;
        &lt;td&gt;✅&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Load OpenStreetMap data to PostGIS&lt;/td&gt;
        &lt;td&gt;✅&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Find and use local SRIDs everywhere&lt;/td&gt;
        &lt;td&gt;✅&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Handle real-world (dirty!) data&lt;/td&gt;
        &lt;td&gt;✅&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Performance of Geometry vs. Geography&lt;/td&gt;
        &lt;td&gt;✅&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Routing&lt;/td&gt;
        &lt;td&gt;✅&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;

</description><pubDate>Sat, 01 Oct 2022 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2022/10/announce-mastering-postgis-openstreetmap</guid></item><item><title>Stubbing toes with &lt;code&gt;auto_explain&lt;/code&gt;</title><link>https://blog.rustprooflabs.com/2022/12/be-careful-auto-explain</link><description>&lt;p&gt;Postgres has a handy module called &lt;code&gt;auto_explain&lt;/code&gt;.  The
&lt;a href="https://www.postgresql.org/docs/current/auto-explain.html"&gt;&lt;code&gt;auto_explain&lt;/code&gt; module&lt;/a&gt;
lives up to its name: it runs &lt;code&gt;EXPLAIN&lt;/code&gt; automatically for you.
The intent for this module is to automatically provide information useful
for troubleshooting about your slow queries as they happen.
This post outlines a pitfall I recently discovered with
&lt;code&gt;auto_explain&lt;/code&gt;.  Luckily for us, it's an easy thing to avoid.&lt;/p&gt;
&lt;p&gt;I discovered this by running &lt;code&gt;CREATE EXTENSION postgis;&lt;/code&gt;
and watching it run for quite a while before failing with an out of disk space error.
That is not my typical experience with a simple &lt;code&gt;CREATE EXTENSION&lt;/code&gt; command!&lt;/p&gt;
&lt;h2&gt;Standard use of &lt;code&gt;auto_explain&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;A common way &lt;code&gt;auto_explain&lt;/code&gt; is used is to target "slow queries" through the setting
&lt;code&gt;auto_explain.log_min_duration&lt;/code&gt;.  This setting defines the number of milliseconds to use
as the threshold of when to log the &lt;code&gt;EXPLAIN&lt;/code&gt; output.  If your queries are typically 10-50 ms,
you might decide to set &lt;code&gt;auto_explain.log_min_duration = 100&lt;/code&gt; to log queries taking twice as
long as your goal.  An instance serving big analytic queries might want to set that much higher,
say 2 or 5 seconds.&lt;/p&gt;
&lt;h2&gt;Innocent testing&lt;/h2&gt;
&lt;p&gt;I say my testing was innocent because I wasn't &lt;strong&gt;trying&lt;/strong&gt; to break something.
That makes it innocent, right?  I was playing around with &lt;code&gt;auto_explain&lt;/code&gt; trying out
&lt;a href="https://www.pgmustard.com/docs/scoring-api"&gt;PgMustard's scoring API&lt;/a&gt;.
At the time I didn't want to think about where to set that threshold... I just wanted to capture
some &lt;code&gt;explain&lt;/code&gt; output for testing.
The &lt;a href="https://www.postgresql.org/docs/current/auto-explain.html"&gt;&lt;code&gt;auto_explain&lt;/code&gt; documentation&lt;/a&gt;
explains that setting &lt;code&gt;auto_explain.log_min_duration = 0&lt;/code&gt;
will capture "all plans."  Sounds good, let's do that!&lt;/p&gt;
</description><pubDate>Tue, 20 Dec 2022 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2022/12/be-careful-auto-explain</guid></item><item><title>H3 indexes for performance with PostGIS data</title><link>https://blog.rustprooflabs.com/2022/06/h3-indexes-on-postgis-data</link><description>&lt;p&gt;I recently started using the H3 hex grid extension in Postgres with the
goal of making some not-so-fast queries faster.
My previous post,
&lt;a href="/2022/04/postgis-h3-intro"&gt;Using Uber's H3 hex grid in PostGIS&lt;/a&gt;,
has an introduction to the H3 extension.
The focus in that post, admittedly, is a PostGIS focused view instead of
an H3 focused view.
This post takes a closer look at using the H3 extension to enhance
performance of spatial searches.&lt;/p&gt;
&lt;p&gt;The two common spatial query patterns considered in this post are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Nearest neighbor style searches&lt;/li&gt;
&lt;li&gt;Regional analysis&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;This post used the H3 v3 extension. See &lt;a href="/2023/05/postgis-h3-v4-refresh"&gt;Using v4 of the Postgres H3 extension&lt;/a&gt; for usage in the latest version.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Setup and Point of Focus&lt;/h2&gt;
&lt;p&gt;This post uses two tables to examine performance.
The following queries add an &lt;code&gt;h3_ix&lt;/code&gt; column to the &lt;code&gt;osm.natural_point&lt;/code&gt;
and &lt;code&gt;osm.building_polygon&lt;/code&gt; tables.  This approach uses
&lt;a href="/2019/12/postgres12-generated-columns-postgis"&gt;&lt;code&gt;GENERATED&lt;/code&gt; columns&lt;/a&gt;
and adds an index to the column. Going through these steps allow us
to remove the need for PostGIS joins at query time for rough distance searches.
See my
&lt;a href="/2022/04/postgis-h3-intro"&gt;previous post&lt;/a&gt; for details about installing
the H3 extension and the basics of how it works.&lt;/p&gt;
</description><pubDate>Fri, 24 Jun 2022 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2022/06/h3-indexes-on-postgis-data</guid></item><item><title>Audit Data with Triggers: PGSQL Phriday #007</title><link>https://blog.rustprooflabs.com/2023/04/pgsqlphriday-007-audit-with-triggers</link><description>&lt;p&gt;Welcome to another &lt;a href="/category/pgsqlphriday"&gt;#PGSQLPhriday post&lt;/a&gt;!
This month's host is Lætitia Avrot, who picked the
&lt;a href="https://mydbanotebook.org/post/triggers/"&gt;topic of Triggers&lt;/a&gt;
with these questions:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"Do you love them? Do you hate them? Do you sometimes love them sometimes hate them? And, most importantly, why? Do you know legitimate use cases for them? How to mitigate their drawbacks (if you think they have any)?"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let's dive in!&lt;/p&gt;
&lt;h2&gt;Triggers are a specialized tool&lt;/h2&gt;
&lt;p&gt;I rarely use triggers.  I don't hate triggers, I just think they should be used
sparingly. Like any specialized tool, you should not expect to use triggers for every
occasion where &lt;em&gt;they could be used&lt;/em&gt;.
However... there is one
notable use where case I really like triggers: &lt;strong&gt;audit tables&lt;/strong&gt;.
Part of the magic of using triggers for auditing data changes in Postgres is
the &lt;code&gt;JSON&lt;/code&gt;/&lt;code&gt;JSONB&lt;/code&gt; support available.&lt;/p&gt;
</description><pubDate>Fri, 07 Apr 2023 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2023/04/pgsqlphriday-007-audit-with-triggers</guid></item><item><title>Setup Geocoder with PostGIS and Tiger/LINE</title><link>https://blog.rustprooflabs.com/2023/10/geocode-with-postgis-setup</link><description>&lt;p&gt;Geocoding addresses is the process of taking a street address
and converting it to its location on a map. This post
shows how to create a PostGIS geocoder using the
U.S. Census Bureau's TIGER/Line data set. This is part one of
a series of posts exploring geocoding addresses.
The &lt;a href="/2023/10/geocode-with-postgis"&gt;next post&lt;/a&gt;
illustrates how to geocode in bulk with a focus on evaluating the accuracy of the resulting geometry data. &lt;/p&gt;
&lt;p&gt;Before diving in, let's look at an example of geocoding.
The address for Union Station
(&lt;a href="https://www.openstreetmap.org/way/25650822"&gt;see on OpenStreetMap&lt;/a&gt;)
is 1701 Wynkoop Street, Denver, CO, 80202.
This address was the input to geocode.
The blue point shown in the following screenshot
is the resulting point from the
&lt;a href="https://postgis.net/docs/Geocode.html"&gt;PostGIS &lt;code&gt;geocode()&lt;/code&gt;&lt;/a&gt;
function. The pop-up dialog shows the address, a rating of 0,
and the calculated distance away from the OpenStreetMap polygon representing that address (13 meters), shown in red under the pop-up
dialog.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Screenshot showing the source polygon for Union Station next to the geocoded point using the street address and the PostGIS Geocoder function." src="/static/images/union-station-source-and-geocoded.png" /&gt;&lt;/p&gt;
</description><pubDate>Sun, 08 Oct 2023 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2023/10/geocode-with-postgis-setup</guid></item><item><title>Working with GPS data in PostGIS</title><link>https://blog.rustprooflabs.com/2023/12/gps-gpx-postgis-processing</link><description>&lt;p&gt;One of the key elements to using PostGIS is having spatial data to work with!
Lucky for us,
one big difference today compared to the not-so-distant past is that essentially
everyone is carrying a GPS unit with them nearly everywhere.  This makes it
easy to create your own GPS data that you can then load into PostGIS!
This post explores some basics of loading GPS data to PostGIS and cleaning
it for use.  It turns out, GPS data fr  om nearly any GPS-enabled device comes
with some... character.  Getting from the raw input to usable spatial data takes a
bit of effort.&lt;/p&gt;
&lt;p&gt;This post starts with using &lt;a href="https://gdal.org/programs/ogr2ogr.html"&gt;ogr2ogr&lt;/a&gt;
to load the &lt;code&gt;.gpx&lt;/code&gt; data to PostGIS.  Once the data is in PostGIS then
we actually want to do something with it.  Before the data is completely
usable, we should spend some time cleaning the data first.
Technically you can start querying the data right away, however, I have found there
is always data cleanup and processing involved first to make the data truly useful.&lt;/p&gt;
&lt;p&gt;This is especially true when using data collected over longer periods of time
with a variety of users and data sources.&lt;/p&gt;
&lt;h2&gt;Travel database project&lt;/h2&gt;
&lt;p&gt;Before I started writing this post I had assumed that all of the code would
be contained in the body of this post.  It turned out that to get to the quality
I wanted, I had to create a new
&lt;a href="https://github.com/rustprooflabs/travel-db"&gt;travel database&lt;/a&gt; project (MIT licensed)
to share the code.  This is already a long post without including a few hundred
more lines of code! The &lt;code&gt;travel-db&lt;/code&gt; project creates a few tables, a view, and a stored procedure
in the &lt;code&gt;travel&lt;/code&gt; schema.  The stored procedure &lt;code&gt;travel.load_bad_elf_points&lt;/code&gt; is
responsible for cleaning an importing the data and weighs in at nearly 500 lines
of code itself.&lt;/p&gt;
</description><pubDate>Mon, 18 Dec 2023 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2023/12/gps-gpx-postgis-processing</guid></item><item><title>PgOSM Flex for Production OpenStreetMap data</title><link>https://blog.rustprooflabs.com/2023/04/pgosm-flex-production-openstreetmap</link><description>&lt;p&gt;The PgOSM Flex Project is looking forward to the 0.8.0!
If you aren't familiar with &lt;a href="https://pgosm-flex.com/"&gt;PgOSM Flex&lt;/a&gt;,
it is a tool that loads high quality OpenStreetMap datasets to PostGIS
using osm2pgsql.
I have a
&lt;a href="/2021/11/postgis-find-openstreetmap-missing-crossing"&gt;few&lt;/a&gt;
&lt;a href="/2022/10/pgrouting-lines-through-polygons"&gt;examples&lt;/a&gt;
of
&lt;a href="/2021/01/pgosm-flex-improved-openstreetmap-places-postgis"&gt;using&lt;/a&gt; OpenStreetMap data loaded
this way.&lt;/p&gt;
&lt;p&gt;I am extremely excited about PgOSM Flex 0.8.0 because the project
as a whole is really starting to feel "production ready."
While I have been using PgOSM Flex in production for
&lt;a href="/2020/12/osm2gpsql-flex-output-to-postgis"&gt;more than 2 years&lt;/a&gt;,
there have been a few rough edges over that time.  However,
the improvements over the past year have brought a number of amazing components
together.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;PgOSM Flex 0.8.0 does include a few ⚠️ breaking changes! ⚠️  Read the &lt;a href="https://github.com/rustprooflabs/pgosm-flex/releases/tag/0.8.0"&gt;release notes&lt;/a&gt; for full details.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;PgOSM Flex in production&lt;/h2&gt;
&lt;p&gt;What does "in production" mean for a tool in a data pipeline?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reliable&lt;/li&gt;
&lt;li&gt;Easy to try out&lt;/li&gt;
&lt;li&gt;Easy to load/update to prod&lt;/li&gt;
&lt;li&gt;Low friction software updates&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This post covers why I think PgOSM Flex meets all of those requirements.&lt;/p&gt;
</description><pubDate>Fri, 21 Apr 2023 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2023/04/pgosm-flex-production-openstreetmap</guid></item><item><title>PGSQL Phriday #005 Recap</title><link>https://blog.rustprooflabs.com/2023/02/pgsql-phriday-005--recap</link><description>&lt;p&gt;Thank you everyone who contributed to &lt;a href="/2023/01/pgsqlphriday-005--postgres-relational-and-otherwise"&gt;PgSQL Phriday #005&lt;/a&gt;! This month's topic:
"Is your data relational?"  If I missed any contributions,
or if new ones are published, let me know and I'll try to update this post.
These snippets are in a somewhat random order, loosely threaded together
by sub-topic.&lt;/p&gt;
&lt;h2&gt;Contributing posts&lt;/h2&gt;
&lt;p&gt;Hetti D. wrote &lt;a href="https://hdombrovskaya.wordpress.com/2023/02/03/pgsql-phriday-005-relational-and-non-relational-data/"&gt;a great post&lt;/a&gt;
starting by addressing the bonus question. I put that question last partly
because I have struggled with a succinct definition myself.
I also put it last because I hoped the initial 3 questions would lead us to answer
the bonus question in our own ways.
Hetti also discusses storing blobs and objects, and considerations between
complexities and trade-offs with more targeted technology.&lt;/p&gt;
</description><pubDate>Fri, 10 Feb 2023 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2023/02/pgsql-phriday-005--recap</guid></item><item><title>Using v4 of the Postgres H3 extension</title><link>https://blog.rustprooflabs.com/2023/05/postgis-h3-v4-refresh</link><description>&lt;p&gt;I wrote about using the H3 extension last year in
&lt;a href="/2022/04/postgis-h3-intro"&gt;Using Uber's H3 hex grid in PostGIS&lt;/a&gt;
and &lt;a href="/2022/06/h3-indexes-on-postgis-data"&gt;H3 indexes for performance with PostGIS data&lt;/a&gt;.
Naturally, things have changed over the past 12 months, specifically
version 4 of the H3 Postgres extension was released.
The &lt;a href="https://github.com/zachasme/h3-pg"&gt;H3 Postgres extension (h3-pg)&lt;/a&gt;
closely follows the upstream
&lt;a href="https://h3geo.org/docs"&gt;H3 project&lt;/a&gt;, including
naming conventions.
The changes made in H3 version 4 unfortunately changed
every function name used in my original blog posts.  It seems this
mass renaming was a one-time alignment in the H3 project, hopefully they
don't all get renamed again.&lt;/p&gt;
&lt;p&gt;This post covers the changes required to migrate the code in my
prior two posts work with version 4.x h3-pg.&lt;/p&gt;
&lt;h2&gt;Create the h3 extension&lt;/h2&gt;
&lt;p&gt;Creating the extension for PostGIS usage now involves installing two (2)
extensions.  Some components have been split out into the &lt;code&gt;h3_postgis&lt;/code&gt;
extension.
I use &lt;code&gt;CASCADE&lt;/code&gt; when installing the &lt;code&gt;h3_postgis&lt;/code&gt; portion since that also
requires &lt;code&gt;postgis_raster&lt;/code&gt; which I do not have installed by default.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE EXTENSION h3;
CREATE EXTENSION h3_postgis CASCADE;
&lt;/code&gt;&lt;/pre&gt;
</description><pubDate>Mon, 22 May 2023 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2023/05/postgis-h3-v4-refresh</guid></item><item><title>PASS Session: Postgres Extensions Shape the Future</title><link>https://blog.rustprooflabs.com/2023/11/pass-2023-extensions-shape-future</link><description>&lt;p&gt;This post supports my session titled &lt;a href="https://passdatacommunitysummit.com/sessions/2014"&gt;PostgreSQL: Extensions Shape the Future&lt;/a&gt;
at PASS Data Community Summit 2023 on November 15.  Thank you to everyone
who joined this session during PASS.  I believe the audio recording with slides
should be made available at some point a few months in the future.&lt;/p&gt;
&lt;h2&gt;Slides&lt;/h2&gt;
&lt;p&gt;The following download is the PDF version of the slide deck.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/static/docs/pass2023--Extensions-Shape-the-Future.pdf"&gt;Extensions Shape the Future slides&lt;/a&gt; (PDF)&lt;/li&gt;
&lt;/ul&gt;
</description><pubDate>Sun, 19 Nov 2023 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2023/11/pass-2023-extensions-shape-future</guid></item><item><title>Pre-conference Session Materials: GIS Data, Queries, and Performance</title><link>https://blog.rustprooflabs.com/2023/11/pass-2023-precon--gis-queries-performance</link><description>&lt;p&gt;This post supports our full day pre-conference session,
&lt;a href="https://passdatacommunitysummit.com/sessions/1515/"&gt;PostGIS and PostgreSQL: GIS Data, Queries, and Performance&lt;/a&gt;
at PASS Data Community Summit 2023 on November 13.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Thank you everyone who participated!  This page has been updated with the slide decks used during the session.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Downloads for session&lt;/h2&gt;
&lt;p&gt;The data, permissions script, and example SQL queries used through this session
are available below. &lt;/p&gt;
</description><pubDate>Sun, 12 Nov 2023 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2023/11/pass-2023-precon--gis-queries-performance</guid></item><item><title>See you at PASS Data Community Summit!</title><link>https://blog.rustprooflabs.com/2023/10/pass-2023-coming-soon</link><description>&lt;p&gt;This year's &lt;a href="https://passdatacommunitysummit.com/"&gt;PASS summit&lt;/a&gt; in Seattle
is only four weeks away!  I am honored that I was selected to provide a full day
&lt;a href="https://passdatacommunitysummit.com/sessions/1515"&gt;pre-conference training&lt;/a&gt;
on PostGIS,
as well as a &lt;a href="https://passdatacommunitysummit.com/sessions/learning-pathways/2014"&gt;general session talk&lt;/a&gt; on extensions.
Both of my topics are focused on the Postgres ecosystem. Of course, that is not
a surprise to my regular readers! It may be a surprise to those who
have been aware of PASS in the past.&lt;/p&gt;
&lt;h2&gt;What is PASS?&lt;/h2&gt;
&lt;p&gt;This year's PASS conference is called "PASS Data Community Summit 2023." 
In the past, PASS was an acronym for Professional Association for SQL Server,
and the conference was very much a Microsoft conference.  When I attended in 2018 it was
because I wanted to learn more about MS SQL Server and PowerBI.
This year, that focus is expanding to include Postgres!&lt;/p&gt;
</description><pubDate>Sun, 15 Oct 2023 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2023/10/pass-2023-coming-soon</guid></item><item><title>Track performance differences with pg_stat_statements</title><link>https://blog.rustprooflabs.com/2023/05/pg-stat-statements-performance-differences</link><description>&lt;p&gt;This is my entry for PgSQL Phriday #008. It's Saturday, so I guess this is a day
late!
This
&lt;a href="https://www.pgmustard.com/blog/pgsql-phriday-pg-stat-statements"&gt;month's topic&lt;/a&gt;,
chosen by Michael from &lt;a href="https://www.pgmustard.com/"&gt;pgMustard&lt;/a&gt;,
is on the excellent &lt;code&gt;pg_stat_statements&lt;/code&gt; extension.
When I saw Michael was the host this month I knew he'd pick a topic I would want
to contribute on!
Michael's post for his own topic
&lt;a href="https://www.pgmustard.com/blog/queries-for-pg-stat-statements"&gt;provides helpful queries&lt;/a&gt; and good reminders about changes to columns
between Postgres version 12 and 13.&lt;/p&gt;
&lt;p&gt;In this post I show one way I like using &lt;code&gt;pg_stat_statements&lt;/code&gt;: tracking the
impact of configuration changes to a specific workload. I used a contrived change
to configuration to quickly make an obvious impact.&lt;/p&gt;
&lt;h2&gt;Process to test&lt;/h2&gt;
&lt;p&gt;I am using &lt;a href="https://pgosm-flex.com/"&gt;PgOSM Flex&lt;/a&gt; to load Colorado OpenStreetMap
data to PostGIS. PgOSM Flex uses a multi-step ETL that
prepares the database, runs &lt;a href="https://osm2pgsql.org/"&gt;osm2pgsql&lt;/a&gt;, and then runs multiple post-processing steps. This results in 2.4 GB of data into Postgres. That should
be enough activity to show something interesting.&lt;/p&gt;
</description><pubDate>Sat, 06 May 2023 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2023/05/pg-stat-statements-performance-differences</guid></item><item><title>Geocode Addresses with PostGIS and Tiger/LINE</title><link>https://blog.rustprooflabs.com/2023/10/geocode-with-postgis</link><description>&lt;p&gt;My previous post,
&lt;a href="/2023/10/geocode-with-postgis-setup"&gt;Setup Geocoder with PostGIS and Tiger/LINE&lt;/a&gt;,
prepared a PostGIS geocoder with TIGER/Line data for Colorado.
This post uses that setup to bulk geocode addresses from
OpenStreetMap buildings to try to determine the accuracy of the geometry
data derived from the input addresses.&lt;/p&gt;
&lt;h2&gt;Quality Expectations&lt;/h2&gt;
&lt;p&gt;Let's get this out of the way:  No geocoding process is going to be perfectly accurate.&lt;/p&gt;
&lt;p&gt;There are a variety of contributing factors to the data quality.
The geocoder data source is pretty decent, coming from the U.S. Census
Bureau's TIGER/Line data set.  The vintage is 2022, and this is as recent
as I can load today using this data source.  We should to understand
that this will not contain any new development or changes from the
past year (or so).&lt;/p&gt;
&lt;p&gt;The OpenStreetMap data is also a source of error.  It is certain
that there are typos, outdated addresses, and other inaccuracies
from the OpenStreetMap data.  Some degree of that has to be expected
with nearly any data source.  The region of OpenStreetMap used will also
be an influence, some regions just don't have many boots-on-the-ground
editing and validating OpenStreetMap data.&lt;/p&gt;
</description><pubDate>Tue, 10 Oct 2023 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2023/10/geocode-with-postgis</guid></item><item><title>Accuracy of Geometry data in PostGIS</title><link>https://blog.rustprooflabs.com/2023/04/postgis-geometry-accuracy</link><description>&lt;p&gt;A common use case with PostGIS data is to calculate things, such as distances
between points, lengths of lines, and the area of polygons. 
The topic of accuracy, or inaccuracy, with &lt;code&gt;GEOMETRY&lt;/code&gt; data comes up often.
The most frequent offenders are generic SRIDs such as 3857 and 4326. In some projects
accuracy is paramount.  Non-negotiable.  On the other hand, plenty of projects
do not need accurate calculations.  Those projects often rely on relationships
between calculations, not the actual values of the calculations themselves.
If Coffee shop Y is 4 times further away than Coffee shop Z. I'll often go to
Coffee shop Z just based on that.&lt;/p&gt;
&lt;p&gt;In most cases, users should still understand how significant the errors are.
This post explores one approach to determine the how accurate (or not!)
the calculations of a given SRID are in a particular region, based on latitude (North/South).
The queries used in this post can be adjusted for your specific area.&lt;/p&gt;
&lt;h2&gt;Set the stage&lt;/h2&gt;
&lt;p&gt;The calculations in this post focus on the distance of two points situated 40 decimal
degrees apart.  The points are created in pairs of west/east points at -120 (W)
and -80 (W).  Those were picked arbitrarily, though intentionally spread far enough
apart to make the errors in distance calculations feel obviously significant.
The point pairs are created in 5 decimal degree intervals of latitude from 80 North to 80 South.
The following screenshot shows how the points frame in much of North America.&lt;/p&gt;
&lt;p&gt;While the points on the map using a &lt;a href="https://en.wikipedia.org/wiki/Mercator_projection"&gt;mercator projection&lt;/a&gt; appear to be equidistant... they are not!&lt;/p&gt;
&lt;p&gt;&lt;img alt="Screenshot showing the points used for distance checks at 5 degree latitude intervals.  The west and east points roughly frame most of North America, the exact longitudes chosen were because they were simple round numbers, for for any other relevance." src="/static/images/geometry-accuracy-points-west-east.png" /&gt;&lt;/p&gt;
</description><pubDate>Sat, 15 Apr 2023 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2023/04/postgis-geometry-accuracy</guid></item><item><title>PostgreSQL 16 improves infinity:  PgSQLPhriday #012</title><link>https://blog.rustprooflabs.com/2023/09/pgsqlphriday-012--postgres16-improves-infinity</link><description>&lt;p&gt;This month's #pgsqlphriday challenge is the &lt;a href="https://www.softwareandbooz.com/a-year-of-pgsql-phriday-blogging-events/"&gt;12th PgSQL Phriday&lt;/a&gt;, marking the end of the first year
of the event!
Before getting into this month's topic I want to give a shout out to Ryan Booz
for &lt;a href="https://www.softwareandbooz.com/pgsql-phriday-001-invite/"&gt;starting #pgsqlphriday&lt;/a&gt;.
More importantly though, a huge &lt;strong&gt;thank you&lt;/strong&gt; to 
the hosts and contributors from the past year! I looked forward to seeing the topic
each month followed by waiting to see who all would contribute and how they would approach
the topic.&lt;/p&gt;
&lt;p&gt;Check out &lt;a href="https://www.pgsqlphriday.com/"&gt;pgsqlphriday.com&lt;/a&gt; for the full list
of topics, including recaps from each topic to link to contributing posts.
This month is the &lt;a href="/category/pgsqlphriday"&gt;7th topic&lt;/a&gt; I've been able to
contribute to the event.  I even had the honor of
hosting #005 with the topic &lt;a href="/2023/02/pgsql-phriday-005--recap"&gt;Is your data relational&lt;/a&gt;?
I'm really looking forward to another year ahead!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Now returning to your regularly scheduled PgSQL Phriday content.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This month,
Ryan Booz chose the topic: &lt;a href="https://www.softwareandbooz.com/pgsql-phriday-012/"&gt;What Excites You About PostgreSQL 16&lt;/a&gt;?   With the release of Postgres 16
expected in the near(ish) future, it's starting to get real. It
won't be long until casual users are upgrading their Postgres instances.
To decide what to write about I headed to the
&lt;a href="https://www.postgresql.org/docs/16/release-16.html"&gt;Postgres 16 release notes&lt;/a&gt;
to scan through the documents. Through all of the items, I picked this item
attributed to Vik Fearing.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Accept the spelling "+infinity" in datetime input&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The rest of this post looks at what this means, and why I think this matters.&lt;/p&gt;
</description><pubDate>Fri, 01 Sep 2023 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2023/09/pgsqlphriday-012--postgres16-improves-infinity</guid></item><item><title>Postgres 15:  Explain Buffer now with Temp Timings</title><link>https://blog.rustprooflabs.com/2023/06/postgres15-explain-buffer-temp-timings</link><description>&lt;p&gt;This post explores a helpful addition to Postgres 15's &lt;code&gt;EXPLAIN&lt;/code&gt; output when
using &lt;code&gt;BUFFERS&lt;/code&gt;.
The Postgres 15 &lt;a href="https://www.postgresql.org/docs/current/release-15.html"&gt;release notes&lt;/a&gt;
mention lists this item:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add &lt;code&gt;EXPLAIN (BUFFERS)&lt;/code&gt; output for temporary file block I/O (Masahiko Sawada)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This improvement adds new detail to the output provided from Postgres 15 when running
&lt;code&gt;EXPLAIN (ANALYZE, BUFFERS) &amp;lt;query&amp;gt;&lt;/code&gt;.  This post explores this feature along with
a couple different ways the reported I/O timing interacts with performance tuning.&lt;/p&gt;
&lt;h2&gt;Getting the feature&lt;/h2&gt;
&lt;p&gt;The first thing you need is to be using at least Postgres 15.
Your instance also needs to have &lt;code&gt;track_io_timing=on&lt;/code&gt; in your Postgres configuration
file, &lt;code&gt;postgresql.conf&lt;/code&gt;. 
Check the value of this setting with &lt;code&gt;SHOW track_io_timing;&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SHOW track_io_timing;
┌─────────────────┐
│ track_io_timing │
╞═════════════════╡
│ on              │
└─────────────────┘
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Test Data and Server&lt;/h2&gt;
&lt;p&gt;This post used a Postgres 15 instance on a
Digital Ocean &lt;a href="https://www.digitalocean.com/products/droplets"&gt;droplet&lt;/a&gt;
with 2 AMD CPU and 2 GB RAM.  I loaded Colorado OpenStreetMap data via
&lt;a href="https://pgosm-flex.com"&gt;PgOSM Flex&lt;/a&gt;.
The data loaded to the &lt;code&gt;osm&lt;/code&gt; schema
weighs in at 2.5 GB, the &lt;code&gt;public&lt;/code&gt; schema, 3.3 GB, has the raw data needed to enable
PgOSM Flex's &lt;code&gt;--replication&lt;/code&gt; feature via osm2pgsql-replication.  The advantage
to having more data than RAM is it's pretty easy to show I/O timings, which I need
for this post!&lt;/p&gt;
</description><pubDate>Sat, 24 Jun 2023 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2023/06/postgres15-explain-buffer-temp-timings</guid></item><item><title>Postgres and Software Development: PGSQL Phriday #004</title><link>https://blog.rustprooflabs.com/2023/01/postgres-software-development</link><description>&lt;p&gt;This blog post is part of PGSQL Phriday #004.
Hettie Dombrovskaya
&lt;a href="https://hdombrovskaya.wordpress.com/2022/12/29/pgsql-phriday-004-postgresql-and-software-development/"&gt;is this month's host&lt;/a&gt;!  I was very excited to
see the topic chosen as Postgres and Software Development.
My contribution to this month's #pgsqlphriday topic covers how I manage
code through our development processes.
Check out &lt;a href="https://hdombrovskaya.wordpress.com/2022/12/29/pgsql-phriday-004-postgresql-and-software-development/"&gt;Hettie's post&lt;/a&gt;
for more about this month's topic.&lt;/p&gt;
&lt;h2&gt;Types of code&lt;/h2&gt;
&lt;p&gt;Before continuing on to the specific questions for the challenge,
I want to define the broad groupings of code I work.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mission critical&lt;/li&gt;
&lt;li&gt;Not trivial&lt;/li&gt;
&lt;li&gt;Trivial&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mission critical code is where most of the "special sauce" is at. Mission
critical SQL code includes DDL commands to create the database structure
such as &lt;code&gt;CREATE TABLE foo&lt;/code&gt; and &lt;code&gt;CREATE VIEW baz&lt;/code&gt;.  This level of code
represents the data structure that enables &lt;strong&gt;everything else&lt;/strong&gt; to function.&lt;/p&gt;
</description><pubDate>Fri, 06 Jan 2023 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2023/01/postgres-software-development</guid></item><item><title>Relational and Non-relational Data: PGSQL Phriday #005</title><link>https://blog.rustprooflabs.com/2023/01/pgsqlphriday-005--postgres-relational-and-otherwise</link><description>&lt;p&gt;Welcome to the 5th installment of the #PGSQLPhriday blogging series. I am
thrilled to be this month's host!  The topic posts should be published by Friday February 3rd.&lt;/p&gt;
&lt;p&gt;When  Ryan Booz &lt;a href="https://www.pgsqlphriday.com/about/"&gt;proposed the idea&lt;/a&gt;
for #PGSQLPhriday I was immediately excited about it.
Other than our first names, Ryan and I have a other few
things in common. One of these common points is we both started our database
careers in the world of MS SQL Server and later found our way to Postgres.
My move to Postgres, and &lt;strong&gt;why&lt;/strong&gt; I discovered Postgres, is at the heart of this
month's topic for PGSQL Phriday 005.&lt;/p&gt;
&lt;h2&gt;Is your data relational?&lt;/h2&gt;
&lt;p&gt;The entire reason I discovered and started using Postgres was
&lt;a href="https://postgis.net/"&gt;PostGIS&lt;/a&gt;.  I needed PostGIS because I had a project in 2011 that
could benefit from the OpenStreetMap data.
The project still needed rock solid support for relational data and the
SQL Standard, which Postgres also provides.
However, it was the spatial support of PostGIS that pulled me into the world of
Postgres.&lt;/p&gt;
</description><pubDate>Mon, 23 Jan 2023 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2023/01/pgsqlphriday-005--postgres-relational-and-otherwise</guid></item><item><title>Load the Right Amount of OpenStreetMap Data</title><link>https://blog.rustprooflabs.com/2023/08/load-right-amount-of-openstreetmap</link><description>&lt;p&gt;Populating a PostGIS database with OpenStreetMap data is favorite way to start
a new geospatial project.  Loading a region of OpenStreetMap data enables you
with data ranging from roads, buildings, water features, amenities, and so much more!
The breadth and bulk of data is great, but it can turn into a hinderance especially
for projects focused on smaller regions.
This post explores how to use &lt;a href="https://pgosm-flex.com/"&gt;PgOSM Flex&lt;/a&gt;
with custom layersets, multiple schemas, and osmium. The goal is load
limited data for a larger region, while loading detailed data for a smaller,
target region.&lt;/p&gt;
&lt;p&gt;The larger region for this post will be the
&lt;a href="https://download.geofabrik.de/north-america/us/colorado.html"&gt;Colorado extract&lt;/a&gt;
from Geofabrik.  The smaller region will be the Fort Collins area, extracted
from the Colorado file.  The following image shows the data loaded in this post
with two maps side-by-side. The minimal data loaded for all of Colorado is shown
on the left and the full details of Fort Collins is on the right.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Image with two maps. The map on the left is a map showing most of Colorado showing place boundaries and major roadways.  The map on the right is a closer view in Fort Collins, Colorado, showing a portion of Colorado State University's campus and residential areas.  The map on the right has details of minor roadways, sidewalks, buildings, and even trees." src="/static/images/right-amount-of-data--co-and-foco.jpg" /&gt;&lt;/p&gt;
</description><pubDate>Thu, 24 Aug 2023 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2023/08/load-right-amount-of-openstreetmap</guid></item><item><title>Postgres Events: PgSQLPhriday #014</title><link>https://blog.rustprooflabs.com/2023/12/pgsqlphriday-014-postgres-events</link><description>&lt;p&gt;It is PgSQLPhriday time again! This month's event is &lt;a href="https://www.cybertec-postgresql.com/en/pgsql-phriday-014-postgresql-events/"&gt;PgSQLPhriday (#014)&lt;/a&gt;
and is hosted by Pavlo Golub.  I'm barely making the deadline, but didn't
want to miss this one!  Pavlo chose &lt;strong&gt;PostgreSQL Events&lt;/strong&gt; for the focus
for this month's topic. See &lt;a href="https://www.cybertec-postgresql.com/en/pgsql-phriday-014-postgresql-events/"&gt;his post&lt;/a&gt; for the full details.
As always, I can't wait to read the rest of the contributions this month.
This post addresses roughly three of his questions.&lt;/p&gt;
&lt;h2&gt;Networking&lt;/h2&gt;
&lt;p&gt;It just so happens, I finally got to meet Pavlo in person
at the &lt;a href="/2023/10/pass-2023-coming-soon"&gt;PASS 2023&lt;/a&gt; summit in Seattle, Washington! 👋&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Q: "Discuss the importance of networking. Have you formed valuable connections or partnerships as a result of these events?"&lt;/p&gt;
&lt;/blockquote&gt;
</description><pubDate>Fri, 01 Dec 2023 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2023/12/pgsqlphriday-014-postgres-events</guid></item><item><title>Postgres is Relational Plus</title><link>https://blog.rustprooflabs.com/2023/02/postgres-relational-plus</link><description>&lt;p&gt;I was &lt;a href="/2023/01/pgsqlphriday-005--postgres-relational-and-otherwise"&gt;the host for this month's #PGSQLPhriday&lt;/a&gt;
topic (#005), and decided on the topic question: &lt;strong&gt;Is your data relational?&lt;/strong&gt;
This is my submission on the topic, and how I use Postgres
for Relational Plus usages.&lt;/p&gt;
&lt;h2&gt;Non-relational data&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; What non-relational data do you store in Postgres and how do you use it?&lt;/p&gt;
&lt;p&gt;PostGIS is the &lt;a href="/category/postgis"&gt;most prominent&lt;/a&gt;
non-relational data I am involved with.
Pretty much all of the PostGIS data I am involved with is rooted alongside
solidly relational data.  Want to know demographics of customers within
10 miles of a specific location?  The location portion is spatial, the
demographic data is relational.&lt;/p&gt;
</description><pubDate>Fri, 03 Feb 2023 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2023/02/postgres-relational-plus</guid></item><item><title>Getting started with MobilityDB</title><link>https://blog.rustprooflabs.com/2023/08/postgis-mobility-db</link><description>&lt;p&gt;The &lt;a href="https://mobilitydb.com/"&gt;MobilityDB&lt;/a&gt; is an exciting project I have been watching for a while.
The &lt;a href="https://github.com/MobilityDB/MobilityDB"&gt;project's README&lt;/a&gt; explains that MobilityDB
"adds support for temporal and spatio-temporal objects."  The spatio-temporal part
translates as PostGIS plus time which is very interesting stuff to me.
I had briefly experimented with the project in its early days and found
a lot of potential. Mobility DB 1.0 was released in April 2022, at the time
of writing the
&lt;a href="https://github.com/MobilityDB/MobilityDB/releases/tag/v1.1.0-alpha"&gt;1.1.0 alpha release&lt;/a&gt;
is available.&lt;/p&gt;
&lt;p&gt;This post explains how I got started with MobilityDB using PostGIS and pgRouting.
I'm using OpenStreetMap roads data with pgRouting to generate trajectories.
If you have gpx traces or other time-aware PostGIS data handy, those could be used
in place of the routes I create with pgRouting.&lt;/p&gt;
&lt;h2&gt;Install MobilityDB&lt;/h2&gt;
&lt;p&gt;When I started working on this post a few weeks ago I had an unexpectedly
difficult time trying to get MobilityDB working.
I was trying to install from the production branch with Postgres 15 and Ubuntu 22.04
and ran into a series of errors.  It turned out the fixes
to allow MobilityDB to work with these latest versions had been in the &lt;code&gt;develop&lt;/code&gt;
branch for more than a year.
After realizing what the problem was I asked a question &lt;a href="https://github.com/MobilityDB/MobilityDB/discussions/355"&gt;and got an answer&lt;/a&gt;. The fixes are now in the &lt;code&gt;master&lt;/code&gt; branch
tagged as &lt;a href="https://github.com/MobilityDB/MobilityDB/releases/tag/v1.1.0-alpha"&gt;1.1.0 alpha&lt;/a&gt;.
Thank you to everyone involved with making that happen!&lt;/p&gt;
&lt;p&gt;To install MobilityDB I'm following the &lt;a href="https://github.com/MobilityDB/MobilityDB#building--installation"&gt;instructions to install from source&lt;/a&gt;. These steps involve &lt;code&gt;git clone&lt;/code&gt;
then using &lt;code&gt;cmake&lt;/code&gt;, &lt;code&gt;make&lt;/code&gt;, and &lt;code&gt;sudo make install&lt;/code&gt;.
&lt;a href="https://github.com/MobilityDB/MobilityDB/discussions/355#discussioncomment-6550678"&gt;Esteban Zimanyi explained&lt;/a&gt;
they are working on getting packaging worked out for providing deb and yum installers.
It looks like work is progressing on those!&lt;/p&gt;
&lt;h2&gt;Update Configuration&lt;/h2&gt;
&lt;p&gt;After installing the extension, the &lt;code&gt;postgresql.conf&lt;/code&gt; needs to be updated to include
PostGIS in the &lt;code&gt;shared_preload_libraries&lt;/code&gt; and increase the &lt;code&gt;max_locks_per_transaction&lt;/code&gt;
to double the default value.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;shared_preload_libraries = 'postgis-3'
max_locks_per_transaction = 128
&lt;/code&gt;&lt;/pre&gt;
</description><pubDate>Tue, 15 Aug 2023 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2023/08/postgis-mobility-db</guid></item><item><title>Can you use ltree for Nested Place Data?</title><link>https://blog.rustprooflabs.com/2024/02/postgres-ltree-nested-places</link><description>&lt;p&gt;The topic of the &lt;a href="https://www.postgresql.org/docs/current/ltree.html"&gt;&lt;code&gt;ltree&lt;/code&gt; data type&lt;/a&gt;
has come up a few times recently.  This intersects with a common type of query
used in PostGIS: nested geometries. An example of nested geometries
is the state of Colorado exists within the United States. The PgOSM Flex
project &lt;a href="https://pgosm-flex.com/query.html?#nested-admin-polygons"&gt;calculates and stores&lt;/a&gt;
nested polygon data from OpenStreetMap places into a handful of array
(&lt;code&gt;TEXT[]&lt;/code&gt;, &lt;code&gt;BIGINT[]&lt;/code&gt;) columns.
I decided to explore &lt;code&gt;ltree&lt;/code&gt; to see if it would be a suitable option for
PgOSM Flex nested places.&lt;/p&gt;
&lt;p&gt;Spoiler alert: &lt;code&gt;ltree&lt;/code&gt; is not suitable for OpenStreetMap data in the way I would
want to use it.&lt;/p&gt;
&lt;h2&gt;Nested data in arrays&lt;/h2&gt;
&lt;p&gt;The following is what the "Colorado is in the U.S" would look like using a
Postgres &lt;code&gt;TEXT[]&lt;/code&gt; array:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{"United States","Colorado"}
&lt;/code&gt;&lt;/pre&gt;
</description><pubDate>Thu, 29 Feb 2024 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2024/02/postgres-ltree-nested-places</guid></item><item><title>UUID in Postgres: PgSQLPhriday #015</title><link>https://blog.rustprooflabs.com/2024/01/postgres-uuid</link><description>&lt;p&gt;This month's PgSQLPhriday #015 topic is about UUIDs. Lætitia Avrot is
this month's host, see &lt;a href="https://mydbanotebook.org/post/uuid-fight/"&gt;her post&lt;/a&gt;
for the full challenge text.  The topic is described as a debate between the Database People
and Developers.  I'm not sure there's such a clean divide on people's opinions
on the topic, as I know plenty of Database People that have settled on using
UUIDs as their default.  Similarly, I know even more developer types that have
followed the arguably more conventional choice of using an auto-incrementing ID.&lt;/p&gt;
&lt;h2&gt;TLDR;&lt;/h2&gt;
&lt;p&gt;I avoid UUIDs. The only places I have used UUIDs in production
are the places where a 3rd party system is involved.&lt;/p&gt;
</description><pubDate>Wed, 31 Jan 2024 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2024/01/postgres-uuid</guid></item><item><title>Hosting a set of Postgres Demo databases</title><link>https://blog.rustprooflabs.com/2024/02/postgres-servers-for-demo</link><description>&lt;p&gt;In April 2023, I submitted my proposal for a
&lt;a href="/2023/11/pass-2023-precon--gis-queries-performance"&gt;full-day pre-conference at PASS 2023&lt;/a&gt;.
My chosen topic was focused on PostGIS, titled &lt;em&gt;GIS Data, Queries, and Performance&lt;/em&gt;.
A key part of my submission was that
the session would be an interactive, follow-along type design. Julie and I believe that
&lt;strong&gt;doing&lt;/strong&gt; is key to learning so we wanted to enforce that as much as possible.
The plan was to use real data and queries to teach a nuanced, technical topic to
an audience of unknown size or background.
I &lt;a href="/2023/10/pass-2023-coming-soon"&gt;also knew&lt;/a&gt;
that PASS is very much a Microsoft focused community.&lt;/p&gt;
&lt;p&gt;Knowing these things, I could not assume specific pre-existing knowledge about
Postgres and PostGIS. I also didn't want to assume they had a Postgres 15 instance
with PostGIS immediately available. I decided the best approach was to
provide participants each a demo Postgres database so they didn't have to worry about those steps.
These demo databases would be pre-loaded with the same
data and extensions I used for my demos.  This would allow participants to
run the same queries, on the same data, on the same general hardware.&lt;/p&gt;
&lt;p&gt;Of course, when my proposal was accepted then I realized I had to figure out
how I was actually going to deliver!  This post explains how I deployed
demo databases to the participants of my PASS 2023 pre-con session.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The net result was a reliable, secure (enough), scalable, and affordable setup.&lt;/p&gt;
&lt;/blockquote&gt;
</description><pubDate>Sat, 10 Feb 2024 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2024/02/postgres-servers-for-demo</guid></item><item><title>Improved Quality in OpenStreetMap Road Network for pgRouting</title><link>https://blog.rustprooflabs.com/2025/12/pgosm-flex-pgrouting-performance-quality-improvements</link><description>&lt;p&gt;Recent changes in the software bundled in &lt;a href="https://pgosm-flex.com/"&gt;PgOSM Flex&lt;/a&gt;
resulted in unexpected improvements when using OpenStreetMap roads data for routing.
The short story: routing with PgOSM Flex 1.2.0 is faster, easier, and
produces higher quality data for routing! I came to this conclusion after completing a
variety of testing with the old and new versions of PgOSM Flex. This post outlines
my testing and findings.&lt;/p&gt;
&lt;p&gt;The concern I had before this testing was that the variety of changes involved in preparing
data for routing in PgOSM Flex 1.2.0 might have degraded routing quality.
I am beyond thrilled with what I found instead. Quality of the generated
network didn't suffer at all, it was a major win!&lt;/p&gt;
&lt;h2&gt;What Changed?&lt;/h2&gt;
&lt;p&gt;The changes started with
&lt;a href="https://github.com/rustprooflabs/pgosm-flex/releases/tag/1.1.1"&gt;PgOSM Flex 1.1.1&lt;/a&gt;
by bumping internal versions used in PgOSM Flex to Postgres 18, PostGIS 3.6, osm2pgsql 2.2.0,
and Debian 13. There was not expected to be any significant changes bundled in that release.
After v1.1.1 was released, it came to my attention that
&lt;a href="https://github.com/pgRouting/pgrouting/releases/tag/v4.0.0"&gt;pgRouting 4.0 had been released&lt;/a&gt;
and that update broke the &lt;a href="https://pgosm-flex.com/routing.html"&gt;routing instructions&lt;/a&gt;
in PgOSM Flex's documentation. This was thankfully
&lt;a href="https://github.com/rustprooflabs/pgosm-flex/issues/408"&gt;reported by Travis Hathaway&lt;/a&gt;
who also helped verify the updates to the process.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;pgRouting 4 removed the &lt;code&gt;pgr_nodeNetwork&lt;/code&gt;, &lt;code&gt;pgr_createTopology&lt;/code&gt;, and &lt;code&gt;pgr_analyzeGraph&lt;/code&gt; functions.
Removing these functions was the catalyst for the changes made in PgOSM Flex 1.2.0.
I had used those &lt;code&gt;pgr_*&lt;/code&gt; functions as part of my core process in data preparation for routing
for as long as I have used pgRouting.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;After &lt;a href="https://github.com/rustprooflabs/pgosm-flex/pull/411"&gt;adjusting the documentation&lt;/a&gt;
it became clear there were
&lt;a href="https://github.com/rustprooflabs/pgosm-flex/issues/408#issuecomment-3675676507"&gt;performance issues&lt;/a&gt; using the replacement functions in pgRouting 4.0, namely in &lt;code&gt;pgr_separateTouching()&lt;/code&gt;.
The performance issue in the pgRouting function is reported as &lt;a href="https://github.com/pgRouting/pgrouting/issues/3010"&gt;pgrouting#3010&lt;/a&gt;.
Working through the performance challenges resulted in
&lt;a href="https://github.com/rustprooflabs/pgosm-flex/releases/tag/1.1.2"&gt;PgOSM Flex 1.1.2&lt;/a&gt;
and ultimately &lt;a href="https://github.com/rustprooflabs/pgosm-flex/releases/tag/1.2.0"&gt;PgOSM Flex 1.2.0&lt;/a&gt;
that now uses a custom procedure to prepare the edge network far better suited
to OpenStreetMap data.&lt;/p&gt;
</description><pubDate>Sun, 28 Dec 2025 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2025/12/pgosm-flex-pgrouting-performance-quality-improvements</guid></item><item><title>Local LLM with OpenWeb UI and Ollama</title><link>https://blog.rustprooflabs.com/2026/03/local-llm-openweb-ui-ollama</link><description>&lt;p&gt;Like much of the world, I have been exploring capabilities and realities of LLMs and other
generative tools for a while now. I am focused on using the
technology with the framing of my technology-focused work, plus my other common scoping
on data privacy and ethics. I want basic
coding help (SQL, Python, Docker, PowerShell, DAX), ideation, writing boilerplate code,
and leveraging existing procedures. Naturally, I want this available offline
in a private and secure environment. I have been focused on running a local LLM with
&lt;a href="https://en.wikipedia.org/wiki/Retrieval-augmented_generation"&gt;RAG capabilities&lt;/a&gt;
and having control over what data goes where, and how it is used.
Especially data about my conversations with the generative LLM.&lt;/p&gt;
&lt;p&gt;This post collects my notes on what my expectations and goals are, and outlines the components
I am using currently, and thoughts on my path forward.&lt;/p&gt;
</description><pubDate>Wed, 18 Mar 2026 05:01:00 GMT</pubDate><guid isPermaLink="true">https://blog.rustprooflabs.com/2026/03/local-llm-openweb-ui-ollama</guid></item></channel></rss>