SQLAlchemy Quick Count

在网页数据展示中,分页是很普遍的操作,在分页逻辑中需要根据数据数据与页面大小计算出页数。对于小数据来说,获取数据集大小的开销可以忽略,但对百万级以上的数据来说,如果不通过合适的优化,随意查询数据集大小的时间开销是恐怖的。这里介绍两种优化的手段:

Query with Primary Key ONLY

减少查询的内容有助于提高查询速度,这点与避免SELECT *是一样的,对于表结构比较复杂以及无法利用covering index的场景来说,计算数据集大小时只考虑主键将极大地提高性能。

Query with ID ONLY
1
count = session.query(Model.id).count()

Approximate Count

对于不需要查询条件的场景来说,直接读取表状态也是一种很好的策略。虽然这种查询的结果不够准确,但对于百万级的数据来说这点误差应该是可以接受的,在处理到需要精确值的环节时再改用别的方法就好了。以下是SQLAlchemy的一个实现:

Count with SHOW TABLE STATUS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def approximate_count(session, table_name):
"""
通过 `SHOW TABLE STATUS` 方法快速查询数据表大小

:param session: SQLAlchemy `Session`
:param table_name: 数据表名
:type table_name: str
"""

result = session.execute('SHOW TABLE STATUS WHERE Name = :table_name', {
'table_name': table_name }).first()

if not result:
raise NoSuchTableError(table_name)

return result['Rows']