[FIX] orm.search_count: ignore `limit`, `offset` and most importantly `order`

These parameters are (or should be) irrelevant for
a search_count(), and they could actually break the
result or make it significantly slower (e.g applying
`order` on large tables).
This fixes a performance regression introduced by
0f43032b.

We could also raise an error offset/limit are
passed in combination with count, but that seems
unnecessary.

Also switched to "SELECT count(1)" for the count
query, as it is simpler and just as fast.
We'd get the same perf with * or any constant value,
as in "SELECT count('me in')", but let's keep it
simple ;-)
This commit is contained in:
Olivier Dony 2014-08-01 12:34:41 +02:00
parent f247bdd0b6
commit e79a3675d1
1 changed files with 7 additions and 6 deletions

View File

@ -4606,18 +4606,19 @@ class BaseModel(object):
order_by = self._generate_order_by(order, query)
from_clause, where_clause, where_clause_params = query.get_sql()
limit_str = limit and ' limit %d' % limit or ''
offset_str = offset and ' offset %d' % offset or ''
where_str = where_clause and (" WHERE %s" % where_clause) or ''
query_str = 'SELECT "%s".id FROM ' % self._table + from_clause + where_str + order_by + limit_str + offset_str
if count:
# /!\ the main query must be executed as a subquery, otherwise
# offset and limit apply to the result of count()!
cr.execute('SELECT count(*) FROM (%s) AS count' % query_str, where_clause_params)
# Ignore order, limit and offset when just counting, they don't make sense and could
# hurt performance
query_str = 'SELECT count(1) FROM ' + from_clause + where_str
cr.execute(query_str, where_clause_params)
res = cr.fetchone()
return res[0]
limit_str = limit and ' limit %d' % limit or ''
offset_str = offset and ' offset %d' % offset or ''
query_str = 'SELECT "%s".id FROM ' % self._table + from_clause + where_str + order_by + limit_str + offset_str
cr.execute(query_str, where_clause_params)
res = cr.fetchall()