簡體   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