2012-12-10 31 views
0

我有一個postgresql表存儲表格形式的數據。繁忙的表性能優化

id SERIAL, 
item_id INTEGER , 
date BIGINT, 
column_id INTEGER, 
row_id INTEGER, 
value TEXT, 
some_flags INTEGER, 

問題是我們每天有5000多個條目,並且信息需要保存多年。 因此,我最終得到一個巨大的桌子女巫忙於頂部1000-5000行, 與大量的SELECT,UPDATE,DELETE查詢,但舊內容很少使用(只在統計數據),幾乎從不改變。

問題是我該如何提高日常工作的性能(從5000萬到5000萬)。 幾乎所有列都有簡單的索引..但沒有什麼奇特的。 目前無法拆分表格,我更期待索引優化。

+1

表是否分區? – 2012-12-10 11:42:00

+4

您可以將'archive'布爾字段添加到您的表中,然後將索引重新創建爲部分索引(即「CREATE INDEX idx_somecol ON my_table(somecol)WHERE NOT archive')。 – dezso

+0

@Jack不,沒有太花哨的基本指標。 –

回答

2

在意見中的建議從dezsoJack都很好。如果你想最簡單的,那麼這是如何實現的部分索引:

create table t ("date" bigint, archive boolean default false); 

insert into t ("date") 
select generate_series(
    extract(epoch from current_timestamp - interval '5 year')::bigint, 
    extract(epoch from current_timestamp)::bigint, 
    5) 
; 

create index the_date_partial_index on t ("date") 
where not archive 
; 

爲了避免改變所有查詢添加索引條件重命名錶:

alter table t rename to t_table; 

,並創建了一個視圖舊名,包括指標條件:

create view t as 
select * 
from t_table 
where not archive 
; 

explain 
select * 
from t 
; 
              QUERY PLAN           
----------------------------------------------------------------------------------------------- 
Index Scan using the_date_partial_index on t_table (cost=0.00..385514.41 rows=86559 width=9) 

然後你每天存檔舊的行:

update t_table 
set archive = true 
where 
    "date" < extract(epoch from current_timestamp - interval '1 week') 
    and 
    not archive 
; 

not archive condiditon是爲了避免更新數百萬已存檔的行。

+0

看起來不錯,但要使用'the_date_partial_index'我必須改變所有的查詢操作與表和'AND歸檔=假/真' –

+0

@ d.raev檢查更新的答案與'視圖'選項 –

+0

我會卡住現在放慢版本,使其變得複雜,現在不是麥芽汁。感謝您的概述:) –