我在MySQL数据库中使用SQLAlchemy,我想计算表中的行数(大约300k).SQLAlchemy count函数的运行时间大约是直接在MySQL中编写同一个查询的50倍.我做错什么了吗?

# this takes over 3 seconds to return
session.query(Segment).count()

然而:

SELECT COUNT(*) FROM segments;
+----------+
| COUNT(*) |
+----------+
|   281992 |
+----------+
1 row in set (0.07 sec)

速度的差异随着表格的大小而增加(在100k行下几乎不明显).

Update

session.query(Segment.id).count()而不是session.query(Segment).count()似乎可以达到这个目的,并使其加速.但我仍然不明白为什么最初的查询速度较慢.

推荐答案

不幸的是,MySQL对子查询的支持非常糟糕,这对我们产生了非常负面的影响.SQLAlchemy docs点指出,可以使用query(func.count(Segment.id))实现"优化"查询:

返回此查询将返回的行数.

这将生成此查询的SQL,如下所示:

SELECT count(1) AS count_1 FROM (
     SELECT <rest of query follows...> ) AS anon_1

要对要计数的特定列进行细粒度控制,请跳过

from sqlalchemy import func

# count User records, without
# using a subquery.
session.query(func.count(User.id))

# return count of user "id" grouped
# by "name"
session.query(func.count(User.id)).\
        group_by(User.name)

from sqlalchemy import distinct

# count distinct "name" values
session.query(func.count(distinct(User.name)))

Mysql相关问答推荐

我可以在插件中访问SQL密钥对吗?

如何有效地计算共同的朋友/追随者?

慢查询日志(log)甚至包括快速查询,因为它包括等待锁定所花费的时间

配置MySQL服务器以管理数千个表

SQL计算不同的列并返回所有行

我是否需要在 N+1 列上建立索引,才能有效地在 N 列上执行 SELECT,并按其他列排序?

MySQL - 事务绑定多个存储过程调用和回滚的简单方法?

如何在 axios 请求中将更新的设置状态值作为参数传递

有没有更好的方法在无限滚动的网页上呈现获取的提要数据?

MySQL如何通过外键ID Select 多行?

Over() 函数不覆盖表中的所有行

WHERE SQL 语句中的列顺序是否重要

用序列号mysql更新列

如何在 Laravel 5.1 中获取数据库中的表列表

MySQL PHP - Select WHERE id = array()?

如何从 MySQL Workbench 中的图表生成 SQL 脚本?

mysql 数据类型仅存储月份和年份

按 15 分钟间隔对 mysql 查询进行分组

为什么 MySQL 自动增量会在插入失败时增加?

如何将具有相同列值的mysql行分组为一行?