2013-03-25 72 views
0

我在PostgreSQL的一個表,其中包含超過10 Milions行,我想更新一個字段:優化PostgreSQL的更新

update annonce set confirmed = true; 

但查詢需要較長時間來執行,我怎樣才能優化這個查詢?

+0

可以添加一些細節?表「看起來」是什麼樣的 - 什麼是列,有索引嗎?你正在更新整個表格還是有涉及的where子句? – gsiems 2013-03-25 17:38:52

+0

該表有一個主鍵,但「確認」是我現在添加的一個表的字段,並且我想將它的值指定爲true。 – 2013-03-25 17:45:47

+0

另請參見:外鍵?看法?其他對象引用表?你能買得起獨家鎖嗎?其他人同時工作?你能承受截斷或刪除?表格有多大(以MB爲單位)你有足夠的可用RAM來暫時保存它嗎? – 2013-03-25 21:53:14

回答

3
update annonce set confirmed = true 
where not confirmed 

部分索引可以幫助:

create index index_name on annonce (confirmed) 
where not confirmed 

比全指數的部分指數將大大降低索引大小,使所有更新,刪除和插入操作變得更快。

+0

爲了加強其他人撰寫的內容,如果未確認的記錄爲表格的10%或更少,則部分索引非常有用。也許你想要一個完全不同的方法,未確認的記錄保存在一個單獨的表中,等待確認?這是否符合業務邏輯? – 2013-03-25 20:35:10

1

如果你經常這樣做,你要稍微修改此如下:

UPDATE announce 
SET confirmed = TRUE 
WHERE NOT confirmed 

此外,你應該(confirmed)創建索引。

今天,你每次都在改變整個表格,這會造成很多死行 - 基本上表格變得臃腫。使用所提出的方法,您將只爲新記錄創建死行,甚至會爲此索引編制索引 - 速度非常快且效率高。

+2

布爾型字段上的索引(或「行數/不同值」比率過高的任何其他字段)基本上沒有用處:它只會生成更多數據和開銷以更新和管理表,而沒有真正的好處。除非你想使用一些奇特的部分索引,但是這又取決於數據和特定情況。 – Eggplant 2013-03-25 17:45:29

+0

@Eggplant你假設這些值是均勻分佈的。如果「未確認」行不超過表格的百分之幾,則可以使用該索引。但這確實浪費了空間,因爲部分索引會更小更快。看到我的答案。 – 2013-03-25 17:52:27

+0

我不明白爲什麼要添加一個索引,我只想更新我添加的字段上的數據,順便說一句,我測試了查詢,它說「查詢完成」,但在我的驗證數據沒有更改。 – 2013-03-25 17:58:18

0

可以說

update announce set confirmed = true where confirmed = false; 

,因爲它是一個布爾值。這將做兩件事情你:

  1. 相比,如果10萬尚未確認公告的數量較少,可以把現場變成一個索引,讓PostgreSQL的使用索引以便更快地訪問。

  2. 在較早版本的postgresql中,免費空間地圖的大小是固定的。如果你更新了一張大桌子,那麼無論你配置了多大的桌子,都會超出這張地圖。因此,您必須定期執行VACUUM FULL,否則數據庫使用的磁盤空間將超出您最大的想象空間。

0

你有三個答案。

他們都是錯的。

沒有人認爲是NULL。而NULL只有這裏需要考慮的事情!因爲,當你在註釋透露:

「證實」是,我現在加入

所有行的定義有confirmed IS NULL表的字段。 A WHERE條款根本無濟於事,只需花費一點點。

即使我們不知道您剛剛添加的列,因爲它在你原來的問題沒有:作爲NULL尚未排除,聲明必須是:

UPDATE announce 
SET confirmed = TRUE 
WHERE confirmed IS DISTINCT FROM TRUE 

但這不會幫助你。相反,索引也沒有。無論如何,整個表格都必須重寫。有沒有辦法繞過它。然而,你可以做很多事情來做到這一點。

都取決於關於您沒有與我們分享的表的信息。

+0

請注意,評論是在答案後發佈的,所以我們假設'未確認的**行**只被添加到已包含大部分「已確認」的大表中。 – 2013-03-26 11:04:24

+0

@ClodoaldoNeto:你有沒有讀過*我的回答?我已經在解決這個問題。所有三個答案都是(並且仍然)*錯誤*首先。它們產生不正確的結果NULL值。 – 2013-03-28 04:40:48

+0

是的,我讀過,我知道其他答案是錯的,包括我的。我在說的是他們錯了,因爲他們在評論中發佈之前已經發布了說明'已確認'列是在已經存在的表格中創建的。 – 2013-03-28 08:00:04