django - 简单查询工作多年,然后突然变慢

标签 django postgresql django-models

我有一个查询已经运行了大约 2 年。数据库表大约有 5000 万行,并且增长缓慢。上周我的一个查询从几乎立即返回到需要几个小时才能运行。

Rank.objects.filter(site=Site.objects.get(profile__client=client, profile__is_active=False)).latest('id')

我已将慢速查询缩小到 Rank 模型。这似乎与使用 latest() 方法有关。如果我只请求一个查询集,它会立即返回一个空的查询集。

#count returns 0 and is fast
Rank.objects.filter(site=Site.objects.get(profile__client=client, profile__is_active=False)).count() == 0
Rank.objects.filter(site=Site.objects.get(profile__client=client, profile__is_active=False)) == [] #also very fast

这是运行 EXPLAIN 的结果。 http://explain.depesz.com/s/wPh

解释分析:http://explain.depesz.com/s/ggi

我尝试用吸尘器吸尘,没有任何变化。 “站点”字段 (ForeignKey) 上已经有一个索引。

奇怪的是,如果我对另一个客户运行相同的查询,而该客户的帐户已经关联了 Rank 对象,那么该查询会再次非常快速地返回。因此,这似乎只是当它们不是该客户端的 Rank 对象时才会出现问题。

有什么想法吗?

版本: Postgres 9.1, Django 1.4 svn 主干版本 17047

最佳答案

嗯,您没有显示实际的 SQL,因此很难确定。但是,explain 输出表明它认为找到匹配项的最快方法是向后扫描“id”上的索引,直到找到有问题的客户端。

既然你说它直到最近都很快,这可能不是一个愚蠢的选择。但是,特定客户的记录总是有可能恰好位于该搜索的最末端。

所以 - 首先尝试两件事:

  1. 对有问题的表进行分析,看看是否为计划者提供了足够的信息。
  2. 如果不是,请增加相关列的统计数据(ALTER TABLE ... SET STATISTICS)并重新分析。看看是否可以。

http://www.postgresql.org/docs/9.1/static/planner-stats.html

如果仍然没有帮助,则考虑在 (client,id) 上建立索引,并删除 id 上的索引(如果其他地方不需要)。那应该给你闪电般的快速答案。

关于django - 简单查询工作多年,然后突然变慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8277088/

相关文章:

django - Django ModelForm 中的复选框和单选按钮

django - 对象没有属性 - HyperlinkedRelatedField

sql - 同一查询中两次更新的意外结果

Django:使用 OneToOneField 扩展用户模型后出现 'no such table'

postgresql - 使用自制软件升级到 PostGIS 2.1 和 PostgreSQL 9.3.1 时缺少库

java - 带有 spring boot JPA Postgresql 的 data.sql 未加载

python - django 根据 max_length 进行过滤

Django继承与外键字段

python - 对 'edit' 进行反向操作,未找到参数 '(9,)' 和关键字参数 '{}'。尝试了 0 个模式 : []

python - 背景图片未显示在 Django 网站上