diff options
| author | Owen Jacobson <owen@grimoire.ca> | 2024-10-23 00:31:53 -0400 |
|---|---|---|
| committer | Owen Jacobson <owen@grimoire.ca> | 2024-10-23 00:42:00 -0400 |
| commit | 3fab58827017041168a769184469cff3722d6c38 (patch) | |
| tree | 043b49c36976a1eec8fe4306a1e88d3cc2a27e62 /src | |
| parent | 6f7f4410980edd13c57ad54697ebe99d739fef76 (diff) | |
Make sure (most) queries avoid table scans.
I've exempted inserts (they never scan in the first place), queries on `event_sequence` (at most one row), and the coalesce()s used for event replay (for now; these are obviously a performance risk area and need addressing).
Method:
```
find .sqlx -name 'query-*.json' -exec jq -r '"explain query plan " + .query + ";"' {} + > explain.sql
```
Then go query by query through the resulting file.
Diffstat (limited to 'src')
| -rw-r--r-- | src/boot/app.rs | 2 | ||||
| -rw-r--r-- | src/channel/repo.rs | 14 | ||||
| -rw-r--r-- | src/login/repo.rs | 2 | ||||
| -rw-r--r-- | src/message/repo.rs | 16 |
4 files changed, 16 insertions, 18 deletions
diff --git a/src/boot/app.rs b/src/boot/app.rs index 1d88608..e716b58 100644 --- a/src/boot/app.rs +++ b/src/boot/app.rs @@ -23,7 +23,7 @@ impl<'a> Boot<'a> { let resume_point = tx.sequence().current().await?; let logins = tx.logins().all(resume_point.into()).await?; - let channels = tx.channels().all(resume_point.into()).await?; + let channels = tx.channels().all(resume_point).await?; let messages = tx.messages().all(resume_point.into()).await?; tx.commit().await?; diff --git a/src/channel/repo.rs b/src/channel/repo.rs index e26ac2b..a49db52 100644 --- a/src/channel/repo.rs +++ b/src/channel/repo.rs @@ -104,13 +104,13 @@ impl<'c> Channels<'c> { Ok(channel) } - pub async fn all(&mut self, resume_at: ResumePoint) -> Result<Vec<History>, LoadError> { + pub async fn all(&mut self, resume_at: Sequence) -> Result<Vec<History>, LoadError> { let channels = sqlx::query!( r#" select id as "id: Id", - name.display_name as "display_name: String", - name.canonical_name as "canonical_name: String", + name.display_name as "display_name?: String", + name.canonical_name as "canonical_name?: String", channel.created_at as "created_at: DateTime", channel.created_sequence as "created_sequence: Sequence", deleted.deleted_at as "deleted_at?: DateTime", @@ -120,7 +120,7 @@ impl<'c> Channels<'c> { using (id) left join channel_deleted as deleted using (id) - where coalesce(channel.created_sequence <= $1, true) + where channel.created_sequence <= $1 order by name.canonical_name "#, resume_at, @@ -144,7 +144,7 @@ impl<'c> Channels<'c> { Ok(channels) } - pub async fn replay(&mut self, resume_at: Option<Sequence>) -> Result<Vec<History>, LoadError> { + pub async fn replay(&mut self, resume_at: ResumePoint) -> Result<Vec<History>, LoadError> { let channels = sqlx::query!( r#" select @@ -263,8 +263,8 @@ impl<'c> Channels<'c> { r#" select channel.id as "id: Id", - name.display_name as "display_name: String", - name.canonical_name as "canonical_name: String", + name.display_name as "display_name?: String", + name.canonical_name as "canonical_name?: String", channel.created_at as "created_at: DateTime", channel.created_sequence as "created_sequence: Sequence", deleted.deleted_at as "deleted_at?: DateTime", diff --git a/src/login/repo.rs b/src/login/repo.rs index c6bc734..611edd6 100644 --- a/src/login/repo.rs +++ b/src/login/repo.rs @@ -69,7 +69,7 @@ impl<'c> Logins<'c> { created_at as "created_at: DateTime" from login where coalesce(created_sequence <= $1, true) - order by created_sequence + order by canonical_name "#, resume_at, ) diff --git a/src/message/repo.rs b/src/message/repo.rs index 4cfefec..c8ceceb 100644 --- a/src/message/repo.rs +++ b/src/message/repo.rs @@ -79,8 +79,8 @@ impl<'c> Messages<'c> { message.body as "body: Body", message.sent_at as "sent_at: DateTime", message.sent_sequence as "sent_sequence: Sequence", - deleted.deleted_at as "deleted_at: DateTime", - deleted.deleted_sequence as "deleted_sequence: Sequence" + deleted.deleted_at as "deleted_at?: DateTime", + deleted.deleted_sequence as "deleted_sequence?: Sequence" from message left join message_deleted as deleted using (id) @@ -186,33 +186,31 @@ impl<'c> Messages<'c> { ) -> Result<History, sqlx::Error> { let id = message.id(); - sqlx::query_scalar!( + sqlx::query!( r#" insert into message_deleted (id, deleted_at, deleted_sequence) values ($1, $2, $3) - returning 1 as "deleted: bool" "#, id, deleted.at, deleted.sequence, ) - .fetch_one(&mut *self.0) + .execute(&mut *self.0) .await?; // Small social responsibility hack here: when a message is deleted, its body is // retconned to have been the empty string. Someone reading the event stream // afterwards, or looking at messages in the channel, cannot retrieve the // "deleted" message by ignoring the deletion event. - sqlx::query_scalar!( + sqlx::query!( r#" update message - set body = "" + set body = '' where id = $1 - returning 1 as "blanked: bool" "#, id, ) - .fetch_one(&mut *self.0) + .execute(&mut *self.0) .await?; let message = self.by_id(id).await?; |
