0

我有以下表「medicion」與以下領域:優化聚集功能和訂購PostgreSQL中

id_variable[int](PK), 
id_departamento[int](PK), 
fecha [date](PK), 
valor [number]`. 

所以,我想要得到的最小,最大和勇氣的通過分組所有數據的平均值id_variable。所以我的查詢是:

SELECT AVG(valor), MIN(valor), MAX(valor) 
FROM medicion 
GROUP BY id_variable; 

知道了默認的PostgreSQL建立主鍵

(id_departamento, id_variable, fecha) 

如何優化這個查詢的索引?我應該只由id_variable或創建新的索引此查詢中的默認索引是否有效?

謝謝!

+0

你有'id_valor'或'valor'?有沒有錯字? –

+0

這是一個錯字,對不起 –

+1

在'id_variable,valor'上添加multicolum覆蓋索引。 PostgreSQL將掃描索引而不是表格。它必須掃描整個索引(或表),因爲使用了AVG功能。 AVG必須始終掃描*所有行*以計算平均值。 – krokodilko

回答

1

由於存在avg(),並且需要所有值來計算平均值,所以它將讀取整個表格。除非你使用WHERE,但沒有WHERE,所以我認爲你需要全局統計。

唯一的東西一個額外的覆蓋索引帶來的是:

  • 不讀取整個表。

這可能是有利的,如果有,例如,50列或文本使表格文件巨大。在這種情況下,讀取整個表來平均一些int值需要從磁盤中榨取大量無用的東西。

我的意思是,當你想從一張巨大的表中狙擊一列或兩列,並且將小列設置在緩存中時,覆蓋索引非常棒。但是在這裏並不是這樣,你只有小列,所以這個原因就沒有了。

  • ...當然由於索引需要更新而稍微慢一些的UPDATE。此外,索引需要緩存,它會使用一些內存等。

  • 獲取行進行預先排序以方便聚合。

這可能很重要,如果它避免巨大的排序。但是,如果它避免了一個哈希聚合,無論如何超快,沒有那麼有用。

現在,如果你的id_variable的相對較少的值不夠...說,足夠適合哈希集合,這可能是一個相當大的數量,取決於你的work_mem ...然後它會很難擊敗它...

如果表格沒有經常更新,或者是隻插入的,並且您經常需要統計信息,請考慮一個物化視圖(保留單獨表中每個id_variable的最小/最大/平均值,以及讓他們在每個插頁上更新)。更新mat-view需要時間,所以如果你經常需要統計信息,這是一個折衷。

如果你不介意它們是陳舊的,你可以將你的統計數據保存在緩存中。或者,如果你的表有大量的舊數據,你可以對它進行分區,並保留舊的只讀分區的最小/最大/總和/計數,並只計算新東西的統計數據。