2017-04-03 22 views
0

私はDjangoで実行しているカスタムクエリを持っています。 pgAdminでクエリを実行すると、応答時間はミリ秒です。しかし、Djangoの同じクエリでは約52秒かかります。Djangoカスタムクエリが極端に遅い

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の出力 - 印刷(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。

sqlはほぼ同じで、応答時間は、次のようになります。filter(antenna_reader__site__slug = 'BVC'、tag__startswith = '3E7')。約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を実行していました。カウントをオーバーしていたため、1つのクエリを使用して合計を戻すことができました。カウントオーバーを使用しても、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

私が示唆できる1つのことは、テーブルにインデックスを追加してみることです。おそらく 't.detected_at'、' s.slug'、 'r.code'です。 –

答えて

0

私は馬鹿だから、それは実際にリンクされたテーブル(外国データラッパー)からのデータを照会しているので...ジャンゴで使用

クエリが遅いです。私は、クエリを実行している結果を、リンクされたテーブルを持つデータベースに直接複製することができます。

postgresqlでリンクテーブルとの結合を高速化する方法を理解する必要があります。

編集: "use_remote_estimate"オプションを使用して、リンクテーブルのクエリを高速化します。 Ex。

ALTER SERVER <servername> OPTIONS (add use_remote_estimate 'true') 
関連する問題