无法修改PostgreSql查询,如何加快速度

时间:2016-11-09 18:58:24

标签: postgresql

我正在寻找加速查询(PostgreSql 9.5),但我无法改变它,因为我无法修改的应用程序执行它。

所以,我从PostgreSql日志中捕获了查询,这里是:

SELECT Count(*)
FROM   (SELECT ti.idturnosistemaexterno,
               ti.historiaclinica_hp,
               p.patientname,
               CASE
                 WHEN ( ti.creationdate :: VARCHAR IS NOT NULL ) THEN
                 Date_trunc('SECOND', ti.creationdate) :: VARCHAR
                 ELSE 'NO EXISTE' :: VARCHAR
               END AS creationdate,
               CASE
                 WHEN ( st.idstudy :: VARCHAR IS NOT NULL ) THEN 'SI' :: VARCHAR
                 ELSE 'NO' :: VARCHAR
               END AS idstudy,
               st.institutionname,
               CASE
                 WHEN ( st.created_time :: VARCHAR IS NOT NULL ) THEN
                 Date_trunc('SECOND', st.created_time) :: VARCHAR
                 ELSE 'NO EXISTE' :: VARCHAR
               END AS created_time,
               ti.enviado,
               st.accessionnumber,
               st.modality
        FROM   study st
               right join turnointegracion ti
                       ON st.accessionnumber = ti.idturnosistemaexterno
               left join patient p
                      ON st.idpatient = p.idpatient
        ORDER  BY ti.creationdate DESC) AS foo; 

explain analyze 输出是这样的:

                                                                       QUERY PLAN                                                                       
--------------------------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=231136.16..231136.17 rows=1 width=0) (actual time=32765.883..32765.883 rows=1 loops=1)
   ->  Sort  (cost=230150.04..230314.39 rows=65741 width=8) (actual time=32754.992..32761.780 rows=64751 loops=1)
         Sort Key: ti.creationdate DESC
         Sort Method: external merge  Disk: 1648kB
         ->  Hash Right Join  (cost=219856.39..224889.28 rows=65741 width=8) (actual time=26653.007..32714.961 rows=64751 loops=1)
               Hash Cond: ((st.accessionnumber)::text = (ti.idturnosistemaexterno)::text)
               ->  Seq Scan on study st  (cost=0.00..4086.26 rows=77126 width=12) (actual time=12.983..6032.251 rows=77106 loops=1)
               ->  Hash  (cost=219048.95..219048.95 rows=64595 width=16) (actual time=26639.722..26639.722 rows=64601 loops=1)
                     Buckets: 65536  Batches: 1  Memory Usage: 3602kB
                     ->  Seq Scan on turnointegracion ti  (cost=0.00..219048.95 rows=64595 width=16) (actual time=17.259..26611.806 rows=64601 loops=1)
 Planning time: 25.519 ms
 Execution time: 32766.710 ms
(12 rows)

以下是相关的表格定义:

表“public.turnointegracion”

          Column           |            Type             |                             Modifiers                              
---------------------------+-----------------------------+--------------------------------------------------------------------
 idturnosistemaexterno     | character varying(50)       | 
 historiaclinica_hp        | integer                     | 
 matriculaprofrealiza      | character varying(10)       | 
 matriculaprofinforma      | character varying(10)       | 
 obrasocial                | character varying(20)       | 
 planobrasocial            | character varying(20)       | 
 nroafiliado               | character varying(20)       | 
 nroautorizacion           | character varying(20)       | 
 matriculaprofprescribe    | character varying(10)       | 
 codigonomenclador         | character varying(10)       | 
 cantidadcodigonomenclador | integer                     | 
 importeunitariohonorarios | money                       | 
 importeunitarioderechos   | money                       | 
 nrodefacturacion          | character varying(15)       | 
 informe                   | bytea                       | 
 titulodelestudio          | character varying(250)      | 
 fechaprescripcion         | timestamp without time zone | 
 fechahora                 | timestamp without time zone | 
 enviado                   | boolean                     | not null default false
 enviadofechahora          | timestamp without time zone | 
 procesado_hp              | timestamp without time zone | 
 modalidad                 | character varying(6)        | 
 orden                     | integer                     | not null default nextval('turnointegracion_orden_seq'::regclass)
 idturno                   | integer                     | not null default nextval('seq_turnointegracion_idturno'::regclass)
 creationdate              | timestamp without time zone | default now()
 informetxt                | text                        | 
 informedisponible         | timestamp without time zone | 
 informeprocesado          | timestamp without time zone | 
Indexes:
    "turnointegracion_pkey" PRIMARY KEY, btree (idturno)
    "idx_fechahora" btree (fechahora)
    "idx_historiaclinicahp" btree (historiaclinica_hp)
    "idx_idturnosistemaexterno" btree (idturnosistemaexterno)
    "idx_informedisponible" btree (informedisponible)
    "idx_turnointegracion_creationdate" btree (creationdate DESC)
    "idx_turnointegracion_idturnosistext_text" btree ((idturnosistemaexterno::text))

表“public.study”

            Column            |            Type             |                        Modifiers                        
------------------------------+-----------------------------+---------------------------------------------------------
 idstudy                      | integer                     | not null default nextval('study_idstudy_seq'::regclass)
 studydate                    | date                        | 
 studytime                    | time without time zone      | 
 studyid                      | character varying(20)       | 
 studydescription             | character varying(255)      | 
 modality                     | character varying(2)        | 
 modalityaetitle              | character varying(50)       | 
 nameofphysiciansreadingstudy | character varying(255)      | 
 accessionnumber              | character varying(20)       | 
 performingphysiciansname     | character varying(255)      | 
 referringphysiciansname      | character varying(255)      | 
 studyinstanceuid             | character varying(255)      | 
 status                       | status_                     | 
 institutionname              | character varying(100)      | 
 idpatient                    | integer                     | 
 created_time                 | timestamp without time zone | 
Indexes:
    "study_pkey" PRIMARY KEY, btree (idstudy)
    "study_studyinstanceuid_key" UNIQUE CONSTRAINT, btree (studyinstanceuid)
    "idx_study_accession_text" btree ((accessionnumber::text))
    "idx_study_accessionnumber" btree (accessionnumber)
    "idx_study_idstudy" btree (idstudy)
Foreign-key constraints:
    "study_idpatient_fkey" FOREIGN KEY (idpatient) REFERENCES patient(idpatient)
Referenced by:
    TABLE "series" CONSTRAINT "series_idstudy_fkey" FOREIGN KEY (idstudy) REFERENCES study(idstudy)

正如您所看到的,我在受影响的列上添加了索引,但规划器仍在执行顺序扫描。有没有办法改善这个?。

1 个答案:

答案 0 :(得分:2)

由于此加入,没有WHERE条件:

right join turnointegracion ti
                   ON st.accessionnumber = ti.idturnosistemaexterno

您正在读取turnointegracion中的所有记录,为“creationdate”添加索引可以加速排序功能,但同样会返回所有记录。

creationdate过滤可缩短最终时间。