我試圖優化一個需要太多時間的查詢。這是我PostgreSQL查詢突然終止,因爲語句超時
- 表1(字段1,字段2 ... field14):包含約850萬行
- 表2(F1,F2,F3):約有250萬個行
查詢是這樣的一個
SELECT
value1,
value2,
value3,
value4,
value5,
hstore(
ARRAY['field9', 'field10', 'field11', 'field12', 'field13', 'field14'],
ARRAY[field9, field10, field11, field12, field13, field14) as metadata,
value7,
(select array((select row(f1, f2) from table2 p where p.f3 = field7))) as values_array
FROM table1
和解釋分析告訴我這
QUERY PLAN
-------------------------------------------------------------------------------------------
Index Scan using table1_pkey on table1 (cost=67846.38..395773.45 rows=8419127 width=88) (actual time=7122.704..22670.680 rows=8419127 loops=1)
InitPlan 2 (returns $1)
-> Result (cost=67846.29..67846.29 rows=1 width=0) (actual time=7009.063..7009.065 rows=1 loops=1)
InitPlan 1 (returns $0)
-> Seq Scan on table2 p (cost=0.00..67846.29 rows=12689 width=20) (actual time=14.971..5069.840 rows=2537787 loops=1)
Filter: (f3 = field7)
所以,有超過表2一個順序掃描(在查詢得到values_array),,而不是索引掃描。難道是因爲SELECT返回表中所有行的大約5-10%? (我聽說,在這種情況下,順序掃描比索引掃描要快,因爲每行所需的I/O操作數量)。
無論如何,該查詢中是否有明顯錯誤?服務器剛剛殺了它,因爲超時
如果我限制行的量加入LIMIT 1000的偏移量返回0,大約需要3分鐘,而是覆蓋整個表(請記住:850萬條記錄)通過移動OFFSET,我需要大約8000次迭代。每個3分鐘意味着超過15天......這是不可接受的。另外,大的OFFSETS也意味着糟糕的表現。
任何見解?在PostgreSQL列表中,他們建議我用JOIN替換內部查詢,並使用複合類型而不是數組。我正在處理這個問題,但我有點困惑,任何意見都是值得歡迎的。
非常感謝!
「在他們推薦的postgresql列表上....」< - link? – 2014-10-30 00:09:48
是的,對不起。看到我的答案。 – jorgeas80 2014-10-30 22:38:21