2011-05-25 73 views
2

我在PostgreSQL表中具有數百萬條記錄和多於一百個字段。
其中之一是日期字段,我們在查詢中按此過濾。爲此日期字段創建索引可提高查詢的性能,但查詢的日期範圍很小,但日期範圍較大,性能下降...使用索引提高Postgresql中查詢的性能

我必須優先考慮其中一個嗎?在不減少大範圍查詢的情況下,可以提高小範圍內的性能?

回答

0

我想嘗試幾件事情:

  • 增加數據庫高速緩存參數
  • 添加在該日期字段上的索引
  • 重新設計/修改應用程序,以較小的範圍內工作(althogh這個建議看起來似乎通常首先被丟棄)
0

創建該日期字段的索引提高了性能上面寫着一個小範圍內的日期查詢電子,但在大範圍內的日期的性能下降...

使用該索引嘗試clustering你的表。性能下降可能是由於整個表在大範圍內打開。如果是這樣,沿着該索引對錶進行聚類將導致更少的磁盤搜索。

0

兩個建議:

1)調查的時間序列數據的使用table inheritance。例如,每月創建一個子表,然後在每個表上指定日期。 PostgreSQL足夠聰明,只能在具有日期範圍內實際數據的子表上執行index_scan。一旦子表由於是新月而被「密封」,請在表上運行CLUSTER以按日期對數據進行排序。

2)看看創建一堆使用WHERE子句的INDEX

建議#1將成爲長期贏家,但將需要一些工作來設置(但會縮放/永遠運行),但如果您的日期範圍有限,建議2可能是一個快速的臨時修復關心掃描。請記住,您只能在INDEXWHERE條款中使用IMMUTABLE函數。

CREATE INDEX tbl_date_2011_05_idx ON tbl(date) WHERE date >= '2011-05-01' AND date <= '2011-06-01'; 
+0

謝謝,但有一個問題,我說的是簡化我的問題的一個日期字段,但實際上我使用兩個日期字段過濾不同querys,一個querys,一個在其他一些,從來沒有兩個與此同時。我寫的問題存在於兩者中。 還有一件事,這兩個日期字段是相似的,我的意思是差異很小(秒或毫秒)。你有時間序列數據的表繼承的一些網址? – 2011-05-25 19:02:29

+0

在場景#1中,如何在正確的子表上插入或更新? – AngerClown 2011-05-25 19:03:19

+0

*(分鐘或秒) – 2011-05-25 19:10:31

3

僅僅使用索引中的信息就無法回答PostgreSQL中的查詢。從正在執行的查詢的角度來看,行是否可見,存儲在主行本身中。所以,當你添加一個索引到的東西,並執行一個使用它的查詢,主要涉及兩個步驟:

  • 導航,以確定哪些數據塊用於
  • 檢索這些塊並返回行的索引匹配查詢

因此,回答具有索引的查詢可能花費比直接訪問數據塊和獲取行更長的時間。發生這種情況的最常見情況是,如果您實際上正在抓取大部分數據。通常情況下,如果使用超過20%的表格,則按順序訪問它會被視爲快速。有時計劃者認爲只有不到20%會被訪問,所以該指數是首選,但事實並非如此;這是添加索引可以減慢查詢速度的一種方法。根據您的描述,這可能是您所看到的情況 - 如果大範圍觸及更多的表格而不是優化程序估計的值,則使用索引可能會導致網絡減速。

爲了解決這個問題,數據庫收集每個表中每列的統計信息,以確定特定的WHERE條件是否足夠有選擇性以使用索引。這個想法是,你不需要閱讀整個表格就可以節省很多塊,在它上面添加索引I/O仍然是一個淨贏。

這種計算可能會出錯,這樣在幾次情況下,您最終會比直接讀取表時執行更多的I/O操作。如果您使用EXPLAIN ANALYZE運行查詢,則會顯示其中大部分原因。如果「預期」值與「實際」值非常不同,則可能表明優化程序在表上的統計數據不準確。另一種可能性是優化器在查詢的選擇性方面犯了一個錯誤 - 它認爲它只會返回少量的行,但實際上它返回了大部分表。在這裏,更好的統計數據是開始在這方面開展工作的正常方法。如果您使用的是PostgreSQL 8.3或更早的版本,默認收集的統計數據量非常低。

某些工作負載最終還會調整random_page_cost可調參數,從而控制此索引與表掃描權衡發生的位置。這只是在檢查統計信息之後才需要考慮的事情。請參閱Tuning Your PostgreSQL Server以瞭解您可以在這裏調整的幾件事情的介紹。