在異動資料庫資料時,蠻常需要在更新完某此資料後,拿到符合條件並且有被更新到的資料是哪些。
有些較舊的程式實作是先執行 UPDATE,然後再用相同條件 SELECT 一次來拿到符合條件的 ID list。
這樣的實作其實較不漂亮,除了在效能上沒比較好,還可能會踩中一些雷。
當系統要吃的量較大的時候,邏輯上來講,能少作一個動作都是幫助(不論這個動作的 effort 有多麼微小)。而先 update 再 select 的實作,就是多了一個 select 的查詢動作。雖然這個 select 的動作,資料可預期會都在資料庫主機的快取裡,但邏輯上來說就是多做了一次動作。
所以當資料庫已經有內建的語法,可以在 update 資料時就將有異動的資料回傳回來,對實作來講,我們就是省下了一個動作,對效能是會有幫助的。
先 Update 再 Select 基本上就是「2」個動作。而這二個動作不管再快,中間都有時間的間隙。所以在 update 完之後,再馬上 select ,如果 select 的條件不夠嚴僅。例:不會包含一些剛才 update 的狀態欄位時,一樣的條件就可能會抓到不應該出現的資料。進而導致後續的處理開始有問題。
新寫的程式,一律都用 returning or bulk returning 來取得被異動資料的相關欄位。legacy code 如果有某些程式入口被打的量慢慢越來越多,改成用 returning 的實作基本上是跑不掉的。
基本上,會不會踩中我說的雷,也是要看整個功能實作的方式。像是 update 的時候如果會異動狀態欄位,並且又能確保相同條件不會同時有其他程式寫資料進來,那理論上就不一定會中這個雷。
只是以實作「漂亮」的程度來講,returning 會是個較好的選擇。尤其是在當你花了很久的時間 trace log,然後發現程式都沒有錯,是錯在這種時間差的問題時,應該不難想像心情有多不美麗……