How Postgres chooses which index to use #26959
Replies: 1 comment 2 replies
-
|
This feels less like a minor integration bug and more like a deployment-safety issue that can impact production reliability. Silently replacing an existing Edge Function named The env var behavior is also concerning. Replacing a project-wide The most important thing here is that none of this appears to have been communicated clearly during installation. The installer messaging says it will deploy Stripe-related Edge Functions, but it does not explicitly warn that it may:
The suggested mitigations are very reasonable and align with standard platform safety practices:
A dry-run style “resources to be created/modified” screen before installation would probably prevent most of these incidents. Also appreciate the detailed recovery notes. The fact that you documented:
makes this much easier for both maintainers and other users to understand and reproduce. For anyone building platform tooling, this is a good example of why installers should behave more like infrastructure migrations than simple one-click add-ons. Production systems need guardrails, especially around globally shared resources and payment infrastructure. Related concepts from Stripe + webhook best practices:
Overall this is a valuable report and definitely seems worth addressing before more teams install Sync Engine into projects that already have existing Stripe infrastructure wired up. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
This is a copy of a troubleshooting article on Supabase's docs site. It may be missing some details from the original. View the original article.
Postgres internals
How an index is chosen
Postgres, internally, contains a few components that manage query execution:
The planner will consider using an index when all the columns referenced are indexed or an indexed column is present in a filter statement, such as:
WHERELIKEILIKEDISTINCTSIMILAR TOJOINORDER BYOtherwise, it will likely perform a full table scan (sequential scan).
In the majority of cases, the indexed column must not only be present but also must be filtered by a comparison operator (
=,>,<>) that is compatible with the index.As an example, one can create the following table:
On the data column, a GIN index can be applied, which is excellent for filtering JSONB datatypes:
Here's a link to the list operators supported by the GIN index; notably, it does not support greater than
>:GIN does support the
@>operator:In most scenarios, developers work with the default BTREE index. It is the most flexible and performant for many data types and is compatible with the following filters operators:
<<==>=>An operator's functional equivalents, such as
IN,BETWEEN, andANY, are also valid.However, just because the base requirements (relevant column, filter, and operators) are present, it doesn't mean that an index will be used. Indexes tend to perform best when searching for data that is not common (represents less than 5% to 10% of a column). If the data is overrepresented, Postgres may still try to use an index, but it can start leaning more towards sequential scans.
Postgres occasionally takes random samples of tables, usually reviewing around 30,000 rows, to determine the frequency of values, and uses that to determine whether an index will be performant.
In very rare cases, these statistics can become stale, and Postgres may opt to use a slower index or sequential scan when a better option is available.
You can see the query plan with the
EXPLAINkeyword:To understand how to interpret its output, you can check out this explainer.
To reset statistics within the database, you can use the following query:
Complex or composite indexes
Multi-column indexes
If you make independent indexes on multiple columns, Postgres will likely use each of them independently to find the relevant rows and then combine the results together.
It is possible to make multi-column indexes. If you are regularly filtering against multiple columns, there can be performance benefits using them instead of several independent indexes.
Ordered indexes
If you're using an ORDER BY clause, indexes can also be pre-sorted by DESC/ASC for better performance.
Functional indexes
Although not as common, indexes can also be leveraged against modified values, such as when using a LOWER function:
Covering indexes
Indexes contain pointers to a specific row, but you could instruct an index to actually hold a copy of a column's value for even faster retrieval. These are known as
coveringindexes. Because maintaining a copy is storage-intensive, you should avoid using it for values with large data footprints. FULL VIDEO ON TOPICIndexes on JSONB
Although a GIN/GIST index can be used to index entire JSONB bodies, you can also target just specific Key-values with standard BTREE indexes:
Beta Was this translation helpful? Give feedback.
All reactions