Opened 3 years ago
Closed 3 years ago
#33460 closed Cleanup/optimization (fixed)
Change SQLite backend to generate INSERT statements using VALUES instead of UNION.
Reported by: | Keryn Knight | Owned by: | Keryn Knight |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | sqlite orm bulk_create batch |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
This is a ticket for tracking this pre-emptive PR.
Django's minimum supported version of SQLite is currently documented as 3.9.
Using INSERT INTO ... VALUES (...)
instead of INSERT INTO ... SELECT UNION ALL ...
for multiple rows (i.e. bulk_create
) was added to SQLite in 3.7.11 released in 2012.
SQLite 3.8.8, released in 2015, further changed it so that VALUES(...)
was not subject to the SQLITE_LIMIT_COMPOUND_SELECT
value, which should subsequently allow for improvements in batch sizes (e.g. investigating changes to django.db.backends.sqlite3.operations.DatabaseOperations.bulk_batch_size
and django.db.backends.sqlite3.features.DatabaseFeatures.max_query_params
, the latter of which supports 32766
values instead of 999
as of 3.32.0)
The documentation for current SQLite (3.37.2) says, of using VALUES(...)
:
The phrase "VALUES(expr-list)" means the same thing as "SELECT expr-list". The phrase "VALUES(expr-list-1),...,(expr-list-N)" means the same thing as "SELECT expr-list-1 UNION ALL ... UNION ALL SELECT expr-list-N". Both forms are the same, except that the number of SELECT statements in a compound is limited by SQLITE_LIMIT_COMPOUND_SELECT whereas the number of rows in a VALUES clause has no arbitrary limit.
There are some restrictions on the use of a VALUES clause that are not shown on the syntax diagrams:
A VALUES clause cannot be followed by ORDER BY.
A VALUES clause cannot be followed by LIMIT.
I have run the test suite against 3.37.2
and whatever the CI versions are (I've not checked) ... so far so good.
Change History (3)
comment:1 by , 3 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:2 by , 3 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
Thanks!