2017-03-16 57 views
3

我有一張桌子可容納大約50M行。我想執行一個簡單的UPDATE查詢:Postgres - 沒有實際的更新,是否有副作用?

UPDATE the_table SET flag = true; 

對於這些行的99%,該標誌已被設置爲true。所以只有1%的行必須改變。

我的問題是:是Postgres足夠聰明知道這一點?或者Postgres會改變這些99%的行,這將導致典型的過程,比如WAL,自動真空,重新索引,同步到奴隸......,對於整個表而言,而不僅僅是這些1%的行。

換句話說,下面的查詢是否更安全?

UPDATE the_table SET flag = true WHERE flag = false; 
+0

它將更新所告知的行數。在你沒有'where'的情況下它會更新所有的行,所以肯定要去第二條語句 –

+0

必須使用where子句,否則所有的行都會受到影響。 – klin

回答

2

Postgres將不是這種情況之間進行區分。但是,這兩種說法的結果並不完全相同;或者至少它們並不普遍。

主要有兩大副作用:

  1. 第一個查詢(沒有WHERE子句)將掃描和處理表中的所有行。在第二種情況下,並且有適當的索引,它可能只會處理幾行。就「桌面上的事物」(禁止觸發器的效果)而言,最終的結果將是相同的。實現這一最終結果所需的時間可能會有很大差異。

  2. 如果表(或視圖)具有trigger是火災「ON UPDATE」和「每一行」(見CREATE TRIGGER),則觸發功能將被要求對錶中的每一行與你的第一個查詢,僅在行WHERE其中條件在第二個上爲真。再次有兩點不同:(1)時間和(2)觸發器的動作。例如,如果觸發器會更新「lastmod」列,則會在第一種情況下更新它的每一行[這可能不是您想要的]。

...和可能的第三之一:

  • 在足夠並行情形:所述第一查詢將阻止在表中的所有行;或者該語句可能因更新某些行而被阻止,因爲另一個事務是同時發生的。所以,無論是漫長的等待時間還是僵局。更新的行數越高,對競爭產生影響的可能性就越高......(或死鎖等)
  • 最常用的更新方式是使用帶有WHERE子句的查詢。一些非常特殊的情況可能會推薦第一種情況(例如,即使該行中其餘的值沒有更新,您也會更新「lastmod」列)。

    「默認情況下」使用WHERE進行查詢。某些數據庫(即:MySQL和safe update)甚至可能不允許您在沒有WHERE子句的情況下執行UPDATE(或DELETE)。

    4

    不,Postgres不檢查您是否更新到相同的值。

    不時地在郵件列表上討論這個問題,但共識是檢查過於昂貴,沒有意義讓所有用戶都支付一些只有少數用戶(通常是用戶糟糕的混淆層 - 又名「ORM」)需要。

    第二種解決方案是進行更新的安全和最佳方式。其中標誌=真標誌=假(或標誌爲空,就此而言)執行更新時

    +0

    混淆圖層 - 又名「ORM」;) – klin

    +1

    @klin:不是ORM代表「混淆關係模型」? :) –

    +2

    我這麼認爲,特別是當我看到如下問題時*我如何在我的ORM中編寫這個查詢?* – klin

    相關問題