Improve speed of getUnreadByConversationAndMarkRead query

Co-authored-by: trevor-signal <131492920+trevor-signal@users.noreply.github.com>
This commit is contained in:
automated-signal
2025-11-14 08:05:36 -06:00
committed by GitHub
parent c5513dbff2
commit 223ea41d62
5 changed files with 36 additions and 19 deletions

View File

@@ -3351,6 +3351,7 @@ function getUnreadByConversationAndMarkRead(
const updateExpirationFragment = sqlFragment`
UPDATE messages
INDEXED BY messages_conversationId_expirationStartTimestamp
SET
expirationStartTimestamp = ${expirationStartTimestamp}
WHERE

View File

@@ -3,18 +3,15 @@
import type { Database } from '@signalapp/sqlcipher';
export default function updateToSchemaVersion1520(db: Database): void {
db.exec(
'DROP INDEX IF EXISTS expiring_message_by_conversation_and_received_at;'
);
export default function updateToSchemaVersion1530(db: Database): void {
db.exec(`
ALTER TABLE messages ADD COLUMN hasExpireTimer INTEGER NOT NULL
GENERATED ALWAYS AS (COALESCE(expireTimer, 0) > 0) VIRTUAL;
`);
db.exec(`
CREATE INDEX messages_conversationId_hasExpireTimer_expirationStartTimestamp
ON messages (conversationId, hasExpireTimer, expirationStartTimestamp);
`);
// Deprecated by migration 1540
// db.exec(`
// CREATE INDEX messages_conversationId_hasExpireTimer_expirationStartTimestamp
// ON messages (conversationId, hasExpireTimer, expirationStartTimestamp);
// `);
}

View File

@@ -0,0 +1,16 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type { Database } from '@signalapp/sqlcipher';
export default function updateToSchemaVersion1540(db: Database): void {
db.exec(
'DROP INDEX IF EXISTS messages_conversationId_hasExpireTimer_expirationStartTimestamp;'
);
db.exec(`
CREATE INDEX messages_conversationId_expirationStartTimestamp
ON messages (conversationId, expirationStartTimestamp)
WHERE hasExpireTimer IS 1;
`);
}

View File

@@ -129,6 +129,7 @@ import updateToSchemaVersion1500 from './1500-search-polls.std.js';
import updateToSchemaVersion1510 from './1510-chat-folders-normalize-all-chats.std.js';
import updateToSchemaVersion1520 from './1520-poll-votes-unread.std.js';
import updateToSchemaVersion1530 from './1530-update-expiring-index.std.js';
import updateToSchemaVersion1540 from './1540-partial-expiring-index.std.js';
import { DataWriter } from '../Server.node.js';
@@ -1616,6 +1617,7 @@ export const SCHEMA_VERSIONS: ReadonlyArray<SchemaUpdateType> = [
{ version: 1510, update: updateToSchemaVersion1510 },
{ version: 1520, update: updateToSchemaVersion1520 },
{ version: 1530, update: updateToSchemaVersion1530 },
{ version: 1540, update: updateToSchemaVersion1540 },
];
export class DBVersionFromFutureError extends Error {

View File

@@ -6,12 +6,12 @@ import { type WritableDB } from '../../sql/Interface.std.js';
import { sql, sqlFragment } from '../../sql/util.std.js';
import { createDB, explain, updateToVersion } from './helpers.node.js';
describe('SQL/updateToSchemaVersion1530', () => {
describe('SQL/updateToSchemaVersion1540', () => {
let db: WritableDB;
beforeEach(() => {
db = createDB();
updateToVersion(db, 1530);
updateToVersion(db, 1540);
});
afterEach(() => {
db.close();
@@ -19,6 +19,7 @@ describe('SQL/updateToSchemaVersion1530', () => {
const CORE_UPDATE_QUERY = sqlFragment`
UPDATE messages
INDEXED BY messages_conversationId_expirationStartTimestamp
SET
expirationStartTimestamp = 342342
WHERE
@@ -48,8 +49,8 @@ describe('SQL/updateToSchemaVersion1530', () => {
assert.strictEqual(
detail,
'SEARCH messages USING INDEX messages_conversationId_hasExpireTimer_expirationStartTimestamp' +
' (conversationId=? AND hasExpireTimer=? AND expirationStartTimestamp=?)'
'SEARCH messages USING INDEX messages_conversationId_expirationStartTimestamp' +
' (conversationId=? AND expirationStartTimestamp=?)'
);
});
it('uses index efficiently with null start + no storyId condition', () => {
@@ -62,8 +63,8 @@ describe('SQL/updateToSchemaVersion1530', () => {
assert.strictEqual(
detail,
'SEARCH messages USING INDEX messages_conversationId_hasExpireTimer_expirationStartTimestamp' +
' (conversationId=? AND hasExpireTimer=? AND expirationStartTimestamp=?)'
'SEARCH messages USING INDEX messages_conversationId_expirationStartTimestamp' +
' (conversationId=? AND expirationStartTimestamp=?)'
);
});
@@ -72,8 +73,8 @@ describe('SQL/updateToSchemaVersion1530', () => {
assert.strictEqual(
detail,
'SEARCH messages USING INDEX messages_conversationId_hasExpireTimer_expirationStartTimestamp' +
' (conversationId=? AND hasExpireTimer=? AND expirationStartTimestamp>?)'
'SEARCH messages USING INDEX messages_conversationId_expirationStartTimestamp' +
' (conversationId=? AND expirationStartTimestamp>?)'
);
});
@@ -86,8 +87,8 @@ describe('SQL/updateToSchemaVersion1530', () => {
assert.strictEqual(
detail,
'SEARCH messages USING INDEX messages_conversationId_hasExpireTimer_expirationStartTimestamp' +
' (conversationId=? AND hasExpireTimer=? AND expirationStartTimestamp>?)'
'SEARCH messages USING INDEX messages_conversationId_expirationStartTimestamp' +
' (conversationId=? AND expirationStartTimestamp>?)'
);
});
});