【发布时间】:2014-04-28 01:19:09
【问题描述】:
我有一个简单的 Django 站点,使用 PostgreSQL 9.3 数据库,有一个存储用户帐户(例如姓名、电子邮件、地址、电话、活动等)的表。但是,我的用户模型相当大,大约有 260 万条记录。我注意到 Django 的管理有点慢,所以使用 django-debug-toolbar,我注意到几乎所有查询都在 1 毫秒内运行,除了:
SELECT COUNT(*) FROM "myapp_myuser" WHERE "myapp_myuser"."active" = true;
大约需要 7000 毫秒。但是,active 列是使用 Django 的标准 db_index=True 进行索引的,它会生成索引:
CREATE INDEX myapp_myuser_active
ON myapp_myuser
USING btree
(active);
通过EXPLAIN 查看查询:
EXPLAIN ANALYZE VERBOSE
SELECT COUNT(*) FROM "myapp_myuser" WHERE "myapp_myuser"."active" = true;
返回:
Aggregate (cost=109305.45..109305.46 rows=1 width=0) (actual time=7342.973..7342.974 rows=1 loops=1)
Output: count(*)
-> Seq Scan on public.myapp_myuser (cost=0.00..102638.16 rows=2666916 width=0) (actual time=0.035..4765.059 rows=2666337 loops=1)
Output: id, created, category_id, name, email, address_1, address_2, city, active, (...)
Filter: myapp_myuser.active
Total runtime: 7343.031 ms
它似乎根本没有使用索引。我读对了吗?
仅运行 SELECT COUNT(*) FROM "myapp_myuser" 在大约 500 毫秒内完成。即使唯一使用的列已编入索引,为什么运行时间会出现如此差异?
如何更好地优化此查询?
【问题讨论】:
-
它没有使用索引。是否有 任何 行“活动”为假?
-
重现性如何?我猜想没有 where 子句的查询会更快,只是因为您在使用 where 子句的查询之后立即运行它,已经将所有数据拉入内存。
标签: django postgresql