Skip to content

Commit 0c19469

Browse files
committed
Optimize SQL reformatting
Add a few bits of caching: 1. Add sub-function to `parse_sql` with `lru_cache`, so that repeat calls with the same query are fast. This saves a lot of processing in N+1 situations. 2. Cache constructed filter stacks in `get_filter_stack()`. This avoids recreating all the various sqlparse objects for each query. 3. Pre-compile the simplification regex. The `re` module already uses an internal LRU cache of regexes, but this avoids recompiling if the regex ever drops out of that cache. Building on top of #1571, this takes run time for the same tested view from ~1100ms to ~950ms, another ~15% saving.
1 parent 5ad50f7 commit 0c19469

File tree

1 file changed

+22
-5
lines changed

1 file changed

+22
-5
lines changed

debug_toolbar/panels/sql/utils.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import re
2+
from functools import lru_cache
23

34
import sqlparse
45
from django.utils.html import escape
@@ -32,22 +33,38 @@ def reformat_sql(sql, with_toggle=False):
3233

3334

3435
def parse_sql(sql, aligned_indent=False):
36+
return _parse_sql(
37+
sql,
38+
dt_settings.get_config()["PRETTIFY_SQL"],
39+
aligned_indent,
40+
)
41+
42+
43+
@lru_cache(maxsize=128)
44+
def _parse_sql(sql, pretty, aligned_indent):
45+
stack = get_filter_stack(pretty, aligned_indent)
46+
return "".join(stack.run(sql))
47+
48+
49+
@lru_cache(maxsize=None)
50+
def get_filter_stack(prettify, aligned_indent):
3551
stack = sqlparse.engine.FilterStack()
36-
if dt_settings.get_config()["PRETTIFY_SQL"]:
52+
if prettify:
3753
stack.enable_grouping()
3854
if aligned_indent:
3955
stack.stmtprocess.append(
4056
sqlparse.filters.AlignedIndentFilter(char="&nbsp;", n="<br/>")
4157
)
4258
stack.preprocess.append(BoldKeywordFilter()) # add our custom filter
4359
stack.postprocess.append(sqlparse.filters.SerializerUnicode()) # tokens -> strings
44-
return "".join(stack.run(sql))
60+
return stack
61+
62+
63+
simplify_re = re.compile(r"SELECT</strong> (...........*?) <strong>FROM")
4564

4665

4766
def simplify(sql):
48-
expr = r"SELECT</strong> (...........*?) <strong>FROM"
49-
sub = r"SELECT</strong> &#8226;&#8226;&#8226; <strong>FROM"
50-
return re.sub(expr, sub, sql)
67+
return simplify_re.sub(r"SELECT</strong> &#8226;&#8226;&#8226; <strong>FROM", sql)
5168

5269

5370
def contrasting_color_generator():

0 commit comments

Comments
 (0)