1
0
mirror of https://github.com/django/django.git synced 2024-12-22 17:16:24 +00:00

Refs #35936 -- Avoided field placeholder lookup for each value inserted.

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.
This commit is contained in:
Simon Charette 2024-11-16 23:34:11 -05:00 committed by Sarah Boyce
parent 918e7a2c76
commit 2638b75554

View File

@ -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,
@ -1703,10 +1703,10 @@ class SQLInsertCompiler(SQLCompiler):
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]
@ -1775,8 +1775,12 @@ class SQLInsertCompiler(SQLCompiler):
# 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
)