Skip to content

perf(drizzle): single-roundtrip db updates for simple collections #13186

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

AlessioGr
Copy link
Member

@AlessioGr AlessioGr commented Jul 16, 2025

Can be reviewed after #13184 is merged.

Currently, an optimized DB update (simple data => no delete-and-create-row) does the following:

  1. sql UPDATE
  2. sql SELECT

This PR reduces this further to one single DB call for simple collections:

  1. sql UPDATE with RETURNING()

This only works for simple collections that do not have any fields that need to be fetched from other tables. If a collection has fields like relationship or blocks, we'll need that separate SELECT call to join in the other tables.

In 4.0, we can remove all "complex" fields from the jobs collection and replace them with a JSON field to make use of this optimization


Copy link
Contributor

github-actions bot commented Jul 16, 2025

📦 esbuild Bundle Analysis for payload

This analysis was generated by esbuild-bundle-analyzer. 🤖
This PR introduced no changes to the esbuild bundle! 🙌

Base automatically changed from perf/further-optimize-upsertRow to main July 16, 2025 16:45
Comment on lines +73 to +80
if (!Object.keys(findManyArgs).length) {
// Optimization - No need for joins => can simply use returning(). This is optimal for very simple collections
// without complex fields that live in separate tables like blocks, arrays, relationships, etc.
const docs = await drizzle
.update(adapter.tables[tableName])
.set(row)
.where(eq(adapter.tables[tableName].id, id))
.returning()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if select is passed? Then findManyArgs here should have the columns key and this condition wouldn't pass, even though it's still a "simple" query. We should handle it instead in returning.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants