From 1d2343fd4e8466b6acaaf466259d377631df29a8 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Fri, 28 Mar 2025 16:45:29 +0100 Subject: [PATCH] perf: optimize SQL queries --- .changeset/many-days-report.md | 5 ++++ .../src/api/durable-objects/queue.ts | 23 ++++++++----------- .../api/durable-objects/sharded-tag-cache.ts | 19 ++++++++------- .../overrides/tag-cache/d1-next-tag-cache.ts | 7 +++--- 4 files changed, 27 insertions(+), 27 deletions(-) create mode 100644 .changeset/many-days-report.md diff --git a/.changeset/many-days-report.md b/.changeset/many-days-report.md new file mode 100644 index 00000000..4cbeda4f --- /dev/null +++ b/.changeset/many-days-report.md @@ -0,0 +1,5 @@ +--- +"@opennextjs/cloudflare": patch +--- + +perf: optimize SQL queries diff --git a/packages/cloudflare/src/api/durable-objects/queue.ts b/packages/cloudflare/src/api/durable-objects/queue.ts index edb76cb5..f1627357 100644 --- a/packages/cloudflare/src/api/durable-objects/queue.ts +++ b/packages/cloudflare/src/api/durable-objects/queue.ts @@ -281,19 +281,16 @@ export class DurableObjectQueueHandler extends DurableObject { checkSyncTable(msg: QueueMessage) { try { if (this.disableSQLite) return false; - const numNewer = this.sql - .exec<{ - numNewer: number; - }>( - "SELECT COUNT(*) as numNewer FROM sync WHERE id = ? AND lastSuccess > ? LIMIT 1", - `${msg.MessageBody.host}${msg.MessageBody.url}`, - Math.round(msg.MessageBody.lastModified / 1000) - ) - .one().numNewer; - - return numNewer > 0; - // eslint-disable-next-line @typescript-eslint/no-unused-vars - } catch (e: unknown) { + return ( + this.sql + .exec( + "SELECT 1 FROM sync WHERE id = ? AND lastSuccess > ? LIMIT 1", + `${msg.MessageBody.host}${msg.MessageBody.url}`, + Math.round(msg.MessageBody.lastModified / 1000) + ) + .toArray().length > 0 + ); + } catch { return false; } } diff --git a/packages/cloudflare/src/api/durable-objects/sharded-tag-cache.ts b/packages/cloudflare/src/api/durable-objects/sharded-tag-cache.ts index 43be4e27..30b537fe 100644 --- a/packages/cloudflare/src/api/durable-objects/sharded-tag-cache.ts +++ b/packages/cloudflare/src/api/durable-objects/sharded-tag-cache.ts @@ -12,16 +12,15 @@ export class DOShardedTagCache extends DurableObject { } async hasBeenRevalidated(tags: string[], lastModified?: number): Promise { - const result = this.sql - .exec<{ - cnt: number; - }>( - `SELECT COUNT(*) as cnt FROM revalidations WHERE tag IN (${tags.map(() => "?").join(", ")}) AND revalidatedAt > ?`, - ...tags, - lastModified ?? Date.now() - ) - .one(); - return result.cnt > 0; + return ( + this.sql + .exec( + `SELECT 1 FROM revalidations WHERE tag IN (${tags.map(() => "?").join(", ")}) AND revalidatedAt > ? LIMIT 1`, + ...tags, + lastModified ?? Date.now() + ) + .toArray().length > 0 + ); } async writeTags(tags: string[], lastModified: number): Promise { diff --git a/packages/cloudflare/src/api/overrides/tag-cache/d1-next-tag-cache.ts b/packages/cloudflare/src/api/overrides/tag-cache/d1-next-tag-cache.ts index 1f61006d..13c60bb5 100644 --- a/packages/cloudflare/src/api/overrides/tag-cache/d1-next-tag-cache.ts +++ b/packages/cloudflare/src/api/overrides/tag-cache/d1-next-tag-cache.ts @@ -15,13 +15,12 @@ export class D1NextModeTagCache implements NextModeTagCache { try { const result = await db .prepare( - `SELECT COUNT(*) as cnt FROM revalidations WHERE tag IN (${tags.map(() => "?").join(", ")}) AND revalidatedAt > ? LIMIT 1` + `SELECT 1 FROM revalidations WHERE tag IN (${tags.map(() => "?").join(", ")}) AND revalidatedAt > ? LIMIT 1` ) .bind(...tags.map((tag) => this.getCacheKey(tag)), lastModified ?? Date.now()) - .first<{ cnt: number }>(); - if (!result) throw new RecoverableError(`D1 select failed for ${tags}`); + .raw(); - return result.cnt > 0; + return result.length > 0; } catch (e) { error(e); // By default we don't want to crash here, so we return false