我有一个自定义查询我正在使用Django运行。如果我在pgAdmin中运行查询,则响应时间为毫秒。但是,Django中的相同查询大约需要52秒。
PgAdmin输出:
EXPLAIN ANALYZE
select t.tag, t.detected_at, a.code as antenna_code, r.code as reader_code, s.slug
from tags_tag t
inner join sites_antenna a on (t.antenna_id = a.id)
inner join sites_reader r on (a.reader_id = r.id)
inner join sites_site s on (r.site_id = s.id)
where s.slug = 'BVC' and tag ~ '3E7'
order by t.detected_at DESC
limit 1
"Limit (cost=5.52..53.02 rows=1 width=37) (actual time=254.105..254.107 rows=1 loops=1)"
" -> Nested Loop (cost=5.52..87869.88 rows=1850 width=37) (actual time=254.101..254.101 rows=1 loops=1)"
" Join Filter: (a.id = t.antenna_id)"
" Rows Removed by Join Filter: 2210"
" -> Index Scan Backward using tags_tag_pkey on tags_tag t (cost=0.43..83561.74 rows=286729 width=31) (actual time=3.928..247.145 rows=369 loops=1)"
" Filter: ((tag)::text ~ '3E7'::text)"
" Rows Removed by Filter: 263"
" -> Materialize (cost=5.09..7.21 rows=1 width=14) (actual time=0.002..0.009 rows=6 loops=369)"
" -> Nested Loop (cost=5.09..7.21 rows=1 width=14) (actual time=0.179..0.237 rows=6 loops=1)"
" -> Hash Join (cost=4.95..6.44 rows=1 width=11) (actual time=0.165..0.195 rows=1 loops=1)"
" Hash Cond: (r.site_id = s.id)"
" -> Seq Scan on sites_reader r (cost=0.00..1.35 rows=35 width=11) (actual time=0.005..0.050 rows=35 loops=1)"
" -> Hash (cost=4.94..4.94 rows=1 width=8) (actual time=0.081..0.081 rows=1 loops=1)"
" Buckets: 1024 Batches: 1 Memory Usage: 9kB"
" -> Seq Scan on sites_site s (cost=0.00..4.94 rows=1 width=8) (actual time=0.043..0.074 rows=1 loops=1)"
" Filter: ((slug)::text = 'BVC'::text)"
" Rows Removed by Filter: 154"
" -> Index Scan using sites_antenna_reader_id_12e342c6_uniq on sites_antenna a (cost=0.14..0.71 rows=6 width=11) (actual time=0.007..0.019 rows=6 loops=1)"
" Index Cond: (reader_id = r.id)"
"Planning time: 28.225 ms"
"Execution time: 254.201 ms"
Django输出 - print(connection.queries)和debug_toolbar:
{'time': '52.940', 'sql': "\n
select t.tag, t.detected_at, a.code as antenna_code, r.code as reader_code, s.slug \n
from tags_tag t\n
inner join sites_antenna a on (t.antenna_id = a.id)\n
inner join sites_reader r on (a.reader_id = r.id)\n
inner join sites_site s on (r.site_id = s.id)\n
where s.slug = 'BVC' and tag ~ '3E7.'\n
order by t.detected_at DESC\n
limit 1\n "}
此外,如果我通过模型运行: tag_b = Tag.objects.filter(antenna__reader__site__slug =' BVC',tag__startswith =' 3E7')。order_by(' -detected_at')。first()
sql几乎完全相同,响应时间约为13秒(仍然太慢)。
{'time': '13.201', 'sql':
'SELECT "tags_tag"."id", "tags_tag"."antenna_id", "tags_tag"."detected_at", "tags_tag"."tag", "tags_tag"."created_at", "tags_tag"."updated_at"
FROM "tags_tag"
INNER JOIN "sites_antenna" ON ("tags_tag"."antenna_id" = "sites_antenna"."id")
INNER JOIN "sites_reader" ON ("sites_antenna"."reader_id" = "sites_reader"."id")
INNER JOIN "sites_site" ON ("sites_reader"."site_id" = "sites_site"."id")
WHERE ("sites_site"."slug" = \'BVC\' AND "tags_tag"."tag"::text LIKE \'3E7%\')
ORDER BY "tags_tag"."detected_at"
DESC LIMIT 1'}
注意:我正在执行自定义sql,因为我正在进行计数,因此我可以使用一个查询来获取总数。即使使用count over,在SQL中,pgadmin和Django的响应时间几乎相同。
select t.tag, t.detected_at, a.code as antenna_code, r.code as reader_code, s.slug, count(*) over () as total_tags
...
有任何想法/建议加快Django的速度吗?
答案 0 :(得分:0)
因为我是个白痴......
Django中使用的查询很慢,因为它实际上是从链接表(Foreign Data Wrapper)查询数据。我可以使用链接表直接在数据库上复制运行查询的结果。
需要弄清楚如何加快postgresql中链接表的连接速度。
编辑:使用选项" use_remote_estimate"加快链接表的查询速度。防爆。
ALTER SERVER <servername> OPTIONS (add use_remote_estimate 'true')