Skip to content

Commit

Permalink
Refs #35936 -- Avoided field placeholder lookup for each value inserted.
Browse files Browse the repository at this point in the history
By building the list of placeholders for each inserted fields once it
doesn't have to be looked up for each inserted rows twice.

The query_values_10000.benchmark.QueryValues10000.time_query_values_10000 ASV
benchmark showed a 5% speed up for 10k items on SQLite for a single field
insertion. Larger performance gains are expected when more fields are involved.
  • Loading branch information
charettes authored and sarahboyce committed Dec 11, 2024
1 parent 918e7a2 commit 2638b75
Showing 1 changed file with 8 additions and 4 deletions.
12 changes: 8 additions & 4 deletions django/db/models/sql/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -1688,7 +1688,7 @@ class SQLInsertCompiler(SQLCompiler):
returning_fields = None
returning_params = ()

def field_as_sql(self, field, val):
def field_as_sql(self, field, get_placeholder, val):
"""
Take a field and a value intended to be saved on that field, and
return placeholder SQL and accompanying params. Check for raw values,
Expand All @@ -1703,10 +1703,10 @@ def field_as_sql(self, field, val):
elif hasattr(val, "as_sql"):
# This is an expression, let's compile it.
sql, params = self.compile(val)
elif hasattr(field, "get_placeholder"):
elif get_placeholder is not None:
# Some fields (e.g. geo fields) need special munging before
# they can be inserted.
sql, params = field.get_placeholder(val, self, self.connection), [val]
sql, params = get_placeholder(val, self, self.connection), [val]
else:
# Return the common case for the placeholder
sql, params = "%s", [val]
Expand Down Expand Up @@ -1775,8 +1775,12 @@ def assemble_as_sql(self, fields, value_rows):

# list of (sql, [params]) tuples for each object to be saved
# Shape: [n_objs][n_fields][2]
get_placeholders = [getattr(field, "get_placeholder", None) for field in fields]
rows_of_fields_as_sql = (
(self.field_as_sql(field, v) for field, v in zip(fields, row))
(
self.field_as_sql(field, get_placeholder, value)
for field, get_placeholder, value in zip(fields, get_placeholders, row)
)
for row in value_rows
)

Expand Down

0 comments on commit 2638b75

Please sign in to comment.