2012-07-23 40 views
1

鑑於我在DB中有3個表格,其中包含來自相同原點的不同數據片段。 所有的表非常相似的結構:來自很多表格的彙總數據

id | parent_id | timestamp | contents 

每個表都具有PARENT_ID(一個家長多條記錄關係)和時間戳指數。

我需要訪問按時間排序的這些數據。目前我使用一個查詢:

prepare query3(bigint) as 
select id, timestamp, contents, filter from 
(select t1.id, t1.timestamp, t1.contents, 'filter1' as filter from table1 t1 
where t1.parent_id = $1 
    union select t2.id, t2.timestamp, t2.contents, 'filter2' as filter from table2 t2 
where t2.parent_id = $1 
    union select t3.id, t3.timestamp, t3.contents, 'filter3' as filter from table3 t3 
where t3.parent_id = $1 
) table_alias order by timestamp; 

由於有相當多的數據在每個表中,它從每次2〜3分鐘,我執行這個查詢。據介紹:650000行和Sort Method: external merge Disk: 186592kB

有什麼方法可以在不改變模式的情況下優化檢索執行時間,但是可以構建更有效的查詢或創建特定的索引?

更新在這裏添加完整的解釋分析結果。在這種情況下,查詢中有4個表格,但我相信在這種情況下3和4之間沒有太大的區別。

"Sort (cost=83569.28..83959.92 rows=156258 width=80) (actual time=2288.871..2442.318 rows=639225 loops=1)" 
" Sort Key: t1.timestamp" 
" Sort Method: external merge Disk: 186592kB" 
" -> Unique (cost=52685.43..54638.65 rows=156258 width=154) (actual time=1572.274..1885.966 rows=639225 loops=1)" 
" -> Sort (cost=52685.43..53076.07 rows=156258 width=154) (actual time=1572.273..1737.041 rows=639225 loops=1)" 
" Sort Key: t1.id, t1.timestamp, t1.contents, ('table1'::text)" 
" Sort Method: external merge Disk: 186624kB" 
"  -> Append (cost=0.00..14635.39 rows=156258 width=154) (actual time=0.070..447.375 rows=639225 loops=1)" 
"  -> Index Scan using table1_parent_id on table1 t1 (cost=0.00..285.08 rows=5668 width=109) (actual time=0.068..5.993 rows=9385 loops=1)" 
"  Index Cond: (parent_id = $1)" 
"  -> Index Scan using table2_parent_id on table2 t2 (cost=0.00..11249.13 rows=132927 width=168) (actual time=0.063..306.567 rows=589056 loops=1)" 
"  Index Cond: (parent_id = $1)" 
"  -> Index Scan using table3_parent_id on table3 t3 (cost=0.00..957.18 rows=4693 width=40) (actual time=25.234..82.381 rows=20176 loops=1)" 
"  Index Cond: (parent_id = $1)" 
"  -> Index Scan using table4_parent_id_idx on table4 t4 (cost=0.00..581.42 rows=12970 width=76) (actual time=0.029..5.894 rows=20608 loops=1)" 
"  Index Cond: (parent_id = $1)" 
"Total runtime: 2489.569 ms" 
+1

您是否曾嘗試將所有這些放在臨時表中? – 2012-07-23 18:19:34

+2

索引parent_id – Samson 2012-07-23 18:21:30

+0

併發布整個解釋 – Samson 2012-07-23 18:21:52

回答

1

你的大部分時間是由於消除工會的重複造成的。使用UNION ALL代替:

select id, timestamp, contents, filter 
from ((select t1.id, t1.timestamp, t1.contents, 'filter1' as filter 
     from table1 t1 
     where t1.parent_id = $1 
     ) 
     union all 
     (select t2.id, t2.timestamp, t2.contents, 'filter2' as filter 
     from table2 t2 
     where t2.parent_id = $1 
     ) 
     union all 
     (select t3.id, t3.timestamp, t3.contents, 'filter3' as filter 
     from table3 t3 
     where t3.parent_id = $1 
     ) 
    ) table_alias 
order by timestamp; 

爲了使這更有效的,你應該有這三個表上PARENT_ID指數。隨着這些變化,它應該運行得非常緊密。

+0

好的。按照您的意圖轉換查詢: – Vestel 2012-07-24 12:08:43

+0

好的。根據用途轉換查詢: 初次查詢第一次運行:60秒,接下來調用10-11秒。 更新後的查詢第一次運行:9秒,下一次調用9-11秒。 – Vestel 2012-07-24 12:21:59