-
Notifications
You must be signed in to change notification settings - Fork 335
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
sqlite: allow pragmas and statements needed to run the query optimizer #3483
base: main
Are you sure you want to change the base?
Conversation
aa67bb3
to
1e99152
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should automatically run PRAGMA optimize
when DOs shut down? Similar to how we take care of enabling autovacuum automatically, etc.
src/workerd/util/sqlite.c++
Outdated
case SQLITE_ANALYZE: /* Table Name NULL */ | ||
KJ_ASSERT(param2 == kj::none); | ||
// We allow all names (including names where isAllowedName() would return false) because a | ||
// SQLite ANALYZE statement with no parameters will analyze all tables, including otherwise |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand correctly, ANALYZE
doesn't return any information to the caller, it just makes notes for future query planning. Is that right? Therefore, it certainly doesn't reveal nor modify the contents of hidden tables, therefore there's no need to restrict it? Might be worth spelling that out in the comment here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your understanding is correct and I've updated the comment.
One non-obvious thing is that the notes that ANALYZE
makes are available in a table that users can modify. This means that customers can make the query planner do suboptimal things. It's likely that the worst thing a customer could do is waste CPU, but it is a rather large surface that we open up by allowing ANALYZE
.
https://www.sqlite.org/lang_analyze.html recommends a bunch of things one can do to optimize the performance of the query planner. Most folks using Durable Objects will probably be best served by just calling `PRAGMA optimize` after making schema changes. A couple of notes about this commit: * `PRAGMA optimize` may call `ANALYZE` on all tables, including the internal `_cf_` tables, so we have to allow `ANALYZE` even on otherwise disallowed table names. * Calls to `ANALYZE`, either directly or via `PRAGMA optimize`, cause the creation of the `sqlite_stat1` table. This caused some noise in sql-test.js as I had to update tests that depend on (a) the particular set of tables in the database and (b) the particular size of the database.
1e99152
to
e2afa2f
Compare
I do think we want either D1 or DO to automatically run The pros of doing the automatic version now are (1) that we probably wouldn't need to allowlist The downsides are: (1) more work to figure out when we can call I'm happy to drop this in favor of the automatic approach if we think that's worth waiting for compared to getting something out sooner. |
https://www.sqlite.org/lang_analyze.html recommends a bunch of things one can do to optimize the performance of the query planner. Most folks using Durable Objects will probably be best served by just calling
PRAGMA optimize
after making schema changes.A couple of notes about this commit:
PRAGMA optimize
may callANALYZE
on all tables, including the internal_cf_
tables, so we have to allowANALYZE
even on otherwise disallowed table names.Calls to
ANALYZE
, either directly or viaPRAGMA optimize
, cause the creation of thesqlite_stat1
table. This caused some noise in sql-test.js as I had to update tests that depend on (a) the particular set of tables in the database and (b) the particular size of the database.