-2

ここに私のSQLとその説明が続きます。パフォーマンスを改善する必要があります。何か案は?パフォーマンスが悪いpostgres sql

のgccでコンパイルx86_64版 - 未知のlinux-gnuの、上のPostgreSQL 9.3.12(Ubuntuの4.8.4-2ubuntu1〜14.04.1)4.8.4、64ビット

explain analyze 
SELECT DISTINCT "apts"."id", practices.name AS alias_0 
FROM "apts" 
LEFT OUTER JOIN "patients" ON "patients"."id" = "apts"."patient_id" 
LEFT OUTER JOIN "practices" ON "practices"."id" = "apts"."practice_id" 
LEFT OUTER JOIN "eligibility_messages" ON "eligibility_messages"."apt_id" = "apts"."id" 
WHERE (apts.eligibility_status_id != 1) 
AND (eligibility_messages.current = 't') 
AND (practices.id = '104') 
ORDER BY practices.name desc 
LIMIT 25 OFFSET 0 


Limit (cost=881321.34..881321.41 rows=25 width=20) (actual time=2928.225..2928.227 rows=25 loops=1) 
-> Sort (cost=881321.34..881391.94 rows=28240 width=20) (actual time=2928.223..2928.224 rows=25 loops=1) 
Sort Key: practices.name 
Sort Method: top-N heapsort Memory: 26kB 
-> HashAggregate (cost=880242.03..880524.43 rows=28240 width=20) (actual time=2927.213..2927.319 rows=520 loops=1) 
-> Nested Loop (cost=286614.55..880100.83 rows=28240 width=20) (actual time=206.180..2926.791 rows=520 loops=1) 
-> Seq Scan on practices (cost=0.00..6.36 rows=1 width=20) (actual time=0.018..0.031 rows=1 loops=1) 
Filter: (id = 104) 
Rows Removed by Filter: 108 
-> Hash Join (cost=286614.55..879812.07 rows=28240 width=8) (actual time=206.159..2926.643 rows=520 loops=1) 
Hash Cond: (eligibility_messages.apt_id = apts.id) 
-> Seq Scan on eligibility_messages (cost=0.00..561275.63 rows=2029532 width=4) (actual time=0.691..2766.867 rows=67559 loops=1) 
Filter: current 
Rows Removed by Filter: 3924633 
-> Hash (cost=284614.02..284614.02 rows=115082 width=12) (actual time=121.957..121.957 rows=91660 loops=1) 
Buckets: 16384 Batches: 2 Memory Usage: 1974kB 
-> Bitmap Heap Scan on apts (cost=8296.88..284614.02 rows=115082 width=12) (actual time=19.927..91.038 rows=91660 loops=1) 
Recheck Cond: (practice_id = 104) 
Filter: (eligibility_status_id <> 1) 
Rows Removed by Filter: 80169 
-> Bitmap Index Scan on index_apts_on_practice_id (cost=0.00..8268.11 rows=177540 width=0) (actual time=16.856..16.856 rows=179506 loops=1) 
Index Cond: (practice_id = 104) 
Total runtime: 2928.361 ms 
+0

検索しているすべての結合値とフィールドにインデックスがありますか?さらに、Eligibility_messagesとPracticesの左外部結合は無効になり、それらを移動して内部結合にすることができます。 practices.nameにインデックスがありますか? – xQbert

答えて

3

まず、書き換えより管理しやすい形にクエリ:

SELECT DISTINCT a."id", pr.name AS alias_0 
FROM "apts" a JOIN 
    "practices" pr 
    ON pr."id" = a."practice_id" JOIN 
    "eligibility_messages" em 
    ON em."apt_id" = a."id" 
WHERE (a.eligibility_status_id <> 1) AND 
     (em.current = 't') AND 
     (a.practice_id = 104) 
ORDER BY pr.name desc ; 

注:

  • WHERE句は、外側がとにかく内部結合に参加するので、あなたは可能性がありますになりますそれらを正しく表現してください。
  • 私は疑いがありますpr.idは実際には文字列です
  • patientsテーブルは使用されていないので、削除しました。
  • おそらく、select distinctは必要ありません。
  • whereの条件を、practicesではなく、aptsに変更しました。

、これは十分に速くない場合は、おそらくapts(practice_id, eligibility_status_id, id)practices(id)、およびeligibility_messages(apt_id, current)に、インデックスをしたいです。

関連する問題