2

我有一個與性能相關的問題。假設我有一個名字爲Michael的用戶。採取以下查詢:更新具有相同值的行是否實際更新行?

UPDATE users 
SET first_name = 'Michael' 
WHERE users.id = 123 

查詢是否會實際執行更新?如果是這樣,我如何防止它發生?

+0

從技術上講,它必須這樣做。如果數據庫決定「嘿,這些值是相同的,我只是假裝我改變了東西」,否則可能會有一個「on update」觸發器。 –

+0

當然可以!如果你不想這樣做,你必須先進行測試,如果不同則進行更新。 – Houari

+0

x-posted to dba.SE:http://dba.stackexchange.com/q/118178/3684 –

回答

2

是的,這是更有效地做到這一點

UPDATE users 
SET first_name = 'Michael' 
WHERE users.id = 123 
and (first_name <> 'Michael' or first_name is null) 

它可以使一個很大的區別。
不只是更新本身的時間 - 它不需要更新鎖定。

+0

也許你的意思是'AND first_name <>'Michael''? – wildplasser

+0

@wildplasser明確 – Paparazzi

+0

它不僅是關於鎖。更新需要*三個磁盤I/O(每頁)。避免冪等更新可以避免它們。 (基於頁面)第二個想法:可能是* 4 * I/O。 – wildplasser

2

PostgreSQL中的UPDATE默認情況下不檢查原始值和新值之間的差異。您可以跳過無用的更新與BEFORE UPDATE觸發:

CREATE OR REPLACE FUNCTION public.update_trigger_skip() 
RETURNS trigger 
LANGUAGE plpgsql 
AS $function$ 
BEGIN 
    IF old IS NOT DISTINCT FROM new THEN 
    RETURN NULL; 
    END IF; 
    RETURN new; 
END; 
$$; 

-- run this trigger as first - start name with "_" 
CREATE TRIGGER _omega_update_skip BEFORE UPDATE ON omega; 
    FOR EACH ROW EXECUTE PROCEDURE update_trigger_skip(); 

的PostgreSQL爲了基於觸發器的名字執行觸發器。這個解決方案很簡單,通用,並且很慢(如果你使用大規模更新 - 對於更新的幾行可以確定)。有觸發器執行的開銷。如果可以,請修改您的查詢,然後執行 - 由@Frisbee描述。

相關問題