Skip to content

Conversation

kezabelle
Copy link
Contributor

@kezabelle kezabelle commented Jan 24, 2022

Edit: ticket is 33460


Instead of using the old work-around of UNION ALL SELECT ...

SQLite 3.7.11 introduced the ability to use multiple values directly; SQLite 3.9 is Django's currently documented minimum supported version.

This looks to have a potentially positive effect on django.db.backends.sqlite3.features.DatabaseFeatures.max_query_params; prior to this change, increasing that value (e.g due to using 3.32+ to get at higher SQLITE_MAX_VARIABLE_NUMBER) would cause test lookup.tests.LookupTests.test_in_bulk_lots_of_ids to fail with django.db.utils.OperationalError: too many terms in compound SELECT but doesn't have that problem afterwards.

(SQLite 3.8.8 made multiple values not subject to the SQLITE_LIMIT_COMPOUND_SELECT)

Queries executed changes from:

INSERT INTO "bulk_create_country" ("name", "iso_two_letter", "description") 
SELECT 'Country 0', '', '' UNION ALL SELECT 'Country 1', '', '' UNION ...

to:

INSERT INTO "bulk_create_country" ("name", "iso_two_letter", "description") 
VALUES ('Country 0', '', ''), ('Country 1', '', ''), ...

Let's see what CI says, for a start!

@kezabelle kezabelle force-pushed the experiment/sqlite_values branch from 8ed1ded to ea8cceb Compare January 24, 2022 13:04
@kezabelle
Copy link
Contributor Author

Tests all passed, but now I've force pushed over the top and so we must go again ;)

From the current SQLite docs:

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.

The VALUES (...) limit was removed in 3.8.8

@felixxm felixxm changed the title Changed SQLite backend's bulk insert to use VALUES (..., ...) Fixed #33460 -- Used VALUES clause for insert in bulk on SQLite. Jan 24, 2022
SQLite 3.7.11 introduced the ability to use multiple values directly.
SQLite 3.8.8 made multiple values not subject to the
SQLITE_LIMIT_COMPOUND_SELECT (500).
@felixxm felixxm force-pushed the experiment/sqlite_values branch from ea8cceb to c27932e Compare January 24, 2022 19:52
@felixxm
Copy link
Member

felixxm commented Jan 24, 2022

@kezabelle Thanks 👍

@felixxm
Copy link
Member

felixxm commented Jan 24, 2022

@kezabelle We should update bulk_batch_size() on SQLite, but I'd like to do so in a separate PR. We need to remember that the SQLITE_MAX_COMPOUND_SELECT limit no longer applies, but only for insert in bulk, and bulk_batch_size() is used in other places:

if len(fields) == 1:
return 500

@felixxm felixxm merged commit c27932e into django:main Jan 24, 2022
@kezabelle
Copy link
Contributor Author

We should update bulk_batch_size() on SQLite, but I'd like to do so in a separate PR. We need to remember that the SQLITE_MAX_COMPOUND_SELECT limit no longer applies, but only for insert in bulk, and bulk_batch_size() is used in other places ...

Yeah, I 100% agree, wasn't planning on even trying to add it to this PR. I need to do some playing around with the batch sizing and the max params and how/where any pain points might occur, but doing so [with any success] requires this PR having landed ... and time ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants