Ric*_*ard 5 django postgresql django-debug-toolbar
我正在使用 Postgres 9.3 运行 Django 1.7,运行runserver. 我的数据库中有大约 2 亿行或大约 80GB 的数据。我正在尝试调试为什么相同的查询在 Postgres 中相当快,但在 Django 中很慢。
数据结构是这样的:
class Chemical(models.Model):
code = models.CharField(max_length=9, primary_key=True)
name = models.CharField(max_length=200)
class Prescription(models.Models):
chemical = models.ForeignKey(Chemical)
... other fields
Run Code Online (Sandbox Code Playgroud)
数据库设置了 C 校对规则和合适的索引:
Table "public.frontend_prescription"
Column | Type | Modifiers
id | integer | not null default nextval('frontend_prescription_id_seq'::regclass)
chemical_id | character varying(9) | not null
Indexes:
"frontend_prescription_pkey" PRIMARY KEY, btree (id)
"frontend_prescription_a69d813a" btree (chemical_id)
"frontend_prescription_chemical_id_4619f68f65c49a8_like" btree (chemical_id varchar_pattern_ops)
Run Code Online (Sandbox Code Playgroud)
这是我的看法:
def chemical(request, bnf_code):
c = get_object_or_404(Chemical, bnf_code=bnf_code)
num_prescriptions = Prescription.objects.filter(chemical=c).count()
context = {
'num_prescriptions': num_prescriptions
}
return render(request, 'chemical.html', context)
Run Code Online (Sandbox Code Playgroud)
瓶颈是.count(). 称呼。Django 调试工具栏显示花费的时间是 2647 毫秒(在下面的“时间”标题下),但解释部分建议花费的时间应该是 621 毫秒(在底部):

更奇怪的是,如果我直接在 Postgres 中运行相同的查询,它似乎只需要 200-300 毫秒:
# explain analyze select count(*) from frontend_prescription where chemical_id='0212000AA';
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------
Aggregate (cost=279495.79..279495.80 rows=1 width=0) (actual time=296.318..296.318 rows=1 loops=1)
-> Bitmap Heap Scan on frontend_prescription (cost=2104.44..279295.83 rows=79983 width=0) (actual time=162.872..276.439 rows=302389 loops=1)
Recheck Cond: ((chemical_id)::text = '0212000AA'::text)
-> Bitmap Index Scan on frontend_prescription_a69d813a (cost=0.00..2084.44 rows=79983 width=0) (actual time=126.235..126.235 rows=322252 loops=1)
Index Cond: ((chemical_id)::text = '0212000AA'::text)
Total runtime: 296.591 ms
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:在调试工具栏中,EXPLAIN 语句与 Django 中的实际性能不同。它仍然比 Postgres 中的原始查询慢。
为什么会出现这种差异?我应该如何调试这个/提高我的 Django 应用程序的性能?
更新:这是另一个随机示例:解释为 350 毫秒,渲染时间超过 10,000!帮助,这使我的 Django 应用程序几乎无法使用。

更新 2:这是另一个慢速(Django 中 40 秒,EXPLAIN 中 600 毫秒...)查询的分析面板。如果我没看错,它表明我认为每个 SQL 调用都需要 13 秒……这是瓶颈吗?

奇怪的是,分析调用仅对于返回大量结果的查询来说很慢,所以我认为延迟不是适用于每个调用的一些 Django 连接开销。
更新 3:我尝试在原始 SQL 中重写视图,现在有时性能更好,尽管我仍然看到大约一半的时间查询缓慢。(我每次都必须创建并重新创建游标,否则我会收到InterfaceError一条关于游标已死的消息 - 不确定这是否对调试有用。我已经设置了CONN_MAX_AGE=1200。)无论如何,这执行正常,尽管很明显它很容易受到注入等的影响,如下所示:
cursor = connection.cursor()
query = "SELECT * from frontend_chemical WHERE code='%s'" % code
c = cursor.execute(query)
c = cursor.fetchone()
cursor.close()
cursor = connection.cursor()
query = "SELECT count(*) FROM frontend_prescription WHERE chemical_id="
query += "'" + code + "';"
cursor.execute(query)
num_prescriptions = cursor.fetchone()[0]
cursor.close()
context = {
'chemical': c,
'num_prescriptions': num_prescriptions
}
return render(request, 'chemical.html', context)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2545 次 |
| 最近记录: |