Closed ForestJohnson closed 1 year ago
For now I managed to resolve some of the issues with database slowness by adding indexes in appropriate places (see #419), so that's part 1 of the fix. Still didn't experiment with views though so best to leave this issue open and come back to it if/when we need it.
I believe you're thinking of materialized views.
SQL light does not support materialized views, only "virtual" views which resolved to normal SQL on the base tables.
https://techdifferences.com/difference-between-view-and-materialized-view.html
Since we haven't really needed to do this, and proper indexing solved a lot of issues we were having, i'm gonna close this (just doing some spring cleaning!)
Any database query that has joins between tables might be a good candidate for a database view.
A database view is like a read-only de-normalized table that gets automatically updated when one of the tables that the view is generated from changes.
Here is an example for notifications:
Tobi described the process of selecting notifications like this:
Forest sez:
The problem is twofold:
target_account_id
but there's no index alongtarget_account_id
on the notifications table.accounts
table in order to display the notification (${owning_account.Username} liked your post!
) and that information is not on the notification rowWe can fix part 1 by simply adding an index along
target_account_id, id
to the notifications table. But we can hit both birds with 1 stone with a view.A view is a nice way to de-normalize because you can think of it as a glorified index, it does not need to be updated by the programmer, it should be updated automatically any time one of its underlying tables is changed.
https://www.tutorialspoint.com/sqlite/sqlite_views.htm
A view is also nice because views can be created, deleted, and updated without interfering with the data/schema in the tables at all, they are derived by the database engine from the view query + the data in the tables.
The query used to generate the view would look something like this:
this way when we run
select * from notification_view where target_account_id = ? and id > ? and id < ?
that where clause will map to a single region of bytes stored on disk in the
notification_view
the the returned rows will have everything needed to serialize the notification well, except for the status details. But it should be fine to do another request for the status details.It will probably be better/faster to:
select * from status where (id = ? or id = ? or id = ? or id = ? or id = ? or ...)
or maybe
select * from status where id in ?
where ? is a list of IDs
Alternatively if the info needed from the status is not very much / not very large, it might be better to simply add it to the notification view:
IIRC the left outer join means that if
notification.status_id
is null, it wont omit that notification row, it will just select null for the rows on the status table.