繁体   English   中英

PostgreSQL查询执行得非常糟糕

[英]Postgresql query is performing really bad

我在Postgresql数据库中查询性能存在巨大问题。 postgresql的版本为: "PostgreSQL 8.4.3 on x86_64-unknown-linux-gnu, compiled by GCC gcc (GCC) 4.1.2 20070115 (prerelease) (SUSE Linux), 64-bit"

我的配置文件设置如下:

shared_buffers = 8GB 
effective_cache_size = 24GB
work_mem = 419430kB 
maintenance_work_mem = 2GB 
checkpoint_segments = 128 
checkpoint_completion_target = 0.9 
wal_buffers = 16MB 
default_statistics_target = 500
constraint_exclusion = on

我需要执行的查询是:

SELECT events.evt_id, events.evt_time, events.device_evt_time , to_ip_char(events.sip) , evt_agent.port , events.rv40 , events.evt , events.msg , events.sun , events.rv35 , events.dun , events.rv45 , events.fn , events.dp , events.trgt_trust_name , events.trgt_trust_domain , events.rv36 , events.rv43 , events.cv21 , events.cv40 , events.cv41 , events.cv42 , events.cv43 , events.cv44 , events.cv50 , events.cv51 , events.cv52 , events.cv53 , events.cv54 , events.cv55 , events.cv56 , events.cv35 , events.cv60 , events.cv61 , events.cv62
FROM events, evt_agent
WHERE 
    events.agent_id = evt_agent.agent_id AND (evt_agent.port::text = ANY (ARRAY['x'::character varying, 'y'::character varying, 'z'::character varying]::text[])) 
    AND events.evt::text <> 'Internal Message'::text
    AND event_time > '2015-12-31 13:23:55.767+00'::timestamptz limit 10;
ORDER BY events.evt_time;

表事件是一个分区表,每天一个分区。 每个分区都有两个约束:

Name    events_p_YYYYMMDDHHMISS_events_p_max_pk
Columns evt_time, evt_id
Name    events_p_YYYYMMDDHHMISS_dc  
Definition  evt_time > '2015-12-04 13:24:25.267973+00'::timestamp with time zone AND evt_time <= '2015-12-05 13:24:25.267973+00'::timestamp with time zone

和七个索引:

Name    events_p_YYYYMMDDHHMISS_events_p_max_identity_ix1   
Columns evt_time, init_usr_identity_guid, rid02 
Operator classes    timestamptz_ops, uuid_ops, int8_ops

Name    events_p_YYYYMMDDHHMISS_events_p_max_identity_ix2   
Columns evt_time, trgt_usr_identity_guid, rid02 
Operator classes    timestamptz_ops, uuid_ops, int8_ops

Name    events_p_YYYYMMDDHHMISS_events_p_max_ix1    
Columns evt_time, sev, agent_id 
Operator classes    timestamptz_ops, int4_ops, int8_ops

Name    events_p_YYYYMMDDHHMISS_events_p_max_ix2    
Columns evt_time, dip, sev  
Operator classes    timestamptz_ops, int4_ops, int4_ops

Name    events_p_YYYYMMDDHHMISS_events_p_max_ix3    
Columns evt_time, res, sev  
Operator classes    timestamptz_ops, text_ops, int4_ops

Name    events_p_YYYYMMDDHHMISS_events_p_max_ix4    
Columns evt_time, sip, sev  
Operator classes    timestamptz_ops, int4_ops, int4_ops

Name    events_p_YYYYMMDDHHMISS_events_p_max_ix5    
Columns evt_time, txnmy_id, agent_id    
Operator classes    timestamptz_ops, int8_ops, int8_ops

表evt_agent是仅包含约20-30行的字典表。

限制:

Name    evt_agent_pk    
Columns agent_id

指标:

Name    evt_agent_ak1   
Columns agent, port, rn, pn, sn, st, device_ctgry, src_id, cust_id  
Operator classes    text_ops, text_ops, text_ops, text_ops, text_ops, text_ops, text_ops, uuid_ops, int8_ops

Name    evt_agent_ix1   
Columns device_ctgry, agent_id  
Operator classes    text_ops, int8_ops

当我执行查询时,我得到了这个解释计划: http : //explain.depesz.com/s/3xcu

Name    evt_agent_ix2   
Columns st, agent_id    
Operator classes    text_ops, int8_ops

Name    test_ev_ag_indx1    
Columns agent_id    
Operator classes    int8_ops

我认为统计信息存在问题,因此我对所有相关表进行了“真空分析”,但查询性能没有得到改善,没有说明计划。

我尝试使用“内部查询”技巧,在这里说明计划: http : //explain.depesz.com/s/FAkH

据我了解,情况变得更糟。

您是否知道如何为该查询获得更好的执行计划? 现在,大约需要42分钟才能从查询中获取任何结果。

提前致谢!

我们将不得不尝试消除哈希联接。 横向连接可能只是答案:

SELECT events.evt_id, events.evt_time, events.device_evt_time , to_ip_char(events.sip) , evt_agent.port , events.rv40 , events.evt , events.msg , events.sun , events.rv35 , events.dun , events.rv45 , events.fn , events.dp , events.trgt_trust_name , events.trgt_trust_domain , events.rv36 , events.rv43 , events.cv21 , events.cv40 , events.cv41 , events.cv42 , events.cv43 , events.cv44 , events.cv50 , events.cv51 , events.cv52 , events.cv53 , events.cv54 , events.cv55 , events.cv56 , events.cv35 , events.cv60 , events.cv61 , events.cv62
FROM evt_agent,  
  LATERAL (SELECT * 
           FROM events AS e
           WHERE
             e.agent_id = evt_agent.agent_id
             AND e.evt::text <> 'Internal Message'::text
             AND e.event_time > '2015-12-31 13:23:55.767+00'::timestamptz 
             LIMIT 10000) AS events
WHERE  (evt_agent.port::text = ANY (ARRAY['x'::character varying, 'y'::character varying, 'z'::character varying]::text[]))         
ORDER BY events.evt_time
LIMIT 10000;

请在没有内部限制的情况下尝试使用此方法,然后发布两者的说明计划。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM