2014-10-29 46 views
1

我試圖優化一個需要太多時間的查詢。這是我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替換內部查詢,並使用複合類型而不是數組。我正在處理這個問題,但我有點困惑,任何意見都是值得歡迎的。

非常感謝!

+0

「在他們推薦的postgresql列表上....」< - link? – 2014-10-30 00:09:48

+0

是的,對不起。看到我的答案。 – jorgeas80 2014-10-30 22:38:21

回答

0

解決,通過表前綴的所有列。該查詢現在看起來像這樣

SELECT 
    a.value1, 
    a.value2, 
    a.value3, 
    a.value4, 
    a.value5, 
    hstore(
     ARRAY['field9', 'field10', 'field11', 'field12', 'field13', 'field14'],  
     ARRAY[a.field9, a.field10, a.field11, a.field12, a.field13, a.field14) as metadata, 
    a.value7, 
    (select array((select row(p.f1, p.f2) from table2 p where p.f3 = a.field7))) as values_array 
FROM table1 a 

問題是table2.f3和table1.field7確實具有相同的名稱。更多的信息在this post of PostgreSQL general list

+0

通過「前綴」你的意思是使用別名,我假設? – 2014-10-31 01:16:31

+0

是的,使用表的別名和別名.column – jorgeas80 2014-10-31 15:58:34