mirror of
https://github.com/reddit-archive/reddit.git
synced 2026-04-05 03:00:15 -04:00
Remove unnecessary conditions from some queries.
PG9 doesn't like the query from _load_link_comments in comment_tree.py. thing.py will automatically filter deleted and spam items out of thing queries if no rules are specified for those columns. To get around this, some queries, including the _load_link_comments one, will specify a rule like _spam == (True, False). This rule was left in the ruleset, despite the fact that it's completely unnecessary from the SQL's standpoint. Its presence then triggered the need of a join against the thing table when only the data table was truly necessary. The query planner in PG9 doesn't like this particular query when it requires a join and will force a full table scan as a result. This patch notes the special case of _spam/_deleted == (True,False) and turns off the default filtering but removes the rules from the query. This saves some WHERE clauses and more importantly removes the need for a JOIN in queries like this one.
This commit is contained in:
@@ -309,6 +309,7 @@ def _load_link_comments(link_id):
|
||||
q = Comment._query(Comment.c.link_id == link_id,
|
||||
Comment.c._deleted == (True, False),
|
||||
Comment.c._spam == (True, False),
|
||||
optimize_rules=True,
|
||||
data = True)
|
||||
comments = list(q)
|
||||
cids = [c._id for c in comments]
|
||||
|
||||
@@ -585,20 +585,28 @@ class Thing(DataThing):
|
||||
bases.deleted, bases.spam, id)
|
||||
|
||||
@classmethod
|
||||
def _query(cls, *rules, **kw):
|
||||
def _query(cls, *all_rules, **kw):
|
||||
need_deleted = True
|
||||
need_spam = True
|
||||
#add default spam/deleted
|
||||
for r in rules:
|
||||
rules = []
|
||||
optimize_rules = kw.pop('optimize_rules', False)
|
||||
for r in all_rules:
|
||||
if not isinstance(r, operators.op):
|
||||
continue
|
||||
if r.lval_name == '_deleted':
|
||||
need_deleted = False
|
||||
# if the caller is explicitly unfiltering based on this column,
|
||||
# we don't need this rule at all. taking this out can save us a
|
||||
# join that is very expensive on pg9.
|
||||
if optimize_rules and r.rval == (True, False):
|
||||
continue
|
||||
elif r.lval_name == '_spam':
|
||||
need_spam = False
|
||||
|
||||
if need_deleted or need_spam:
|
||||
rules = list(rules)
|
||||
# see above for explanation
|
||||
if optimize_rules and r.rval == (True, False):
|
||||
continue
|
||||
rules.append(r)
|
||||
|
||||
if need_deleted:
|
||||
rules.append(cls.c._deleted == False)
|
||||
|
||||
Reference in New Issue
Block a user