大家好,我是架構擺渡人。這是實踐經驗系列的第七篇文章,這個系列會給大家分享很多在實際工作中有用的經驗,如果有收穫,還請分享給更多的朋友。
今天給大家分享一個容易忽略的問題,正是因為容易忽略,所以才要重視。
我們的業務表中有兩個欄位是必不可少的,分別是建立時間和修改時間,這樣就知道資料是什麼時候建立的,最後一次的修改時間是什麼時候。
就是經常會在修改時間上看到這個語句ON UPDATE CURRENT_TIMESTAMP,SQL語句如下:
`update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
也就是說update_time這個欄位不需要我們手動去維護,只要這行資料有修改,就會自動更新update_time,非常方便的一個功能。
但這個功能如果沒用好,是很有可能帶來嚴重的問題,下面給大家介紹下會帶來什麼問題?
在某個業務場景下,會使用update_time來進行範圍查詢,也就是查詢增量更新的資料。正常情況下是沒有問題的,功能也跑了很久。突然有一天,這個查詢大量報錯,SQL都是超時的情況,並且影響了其他的業務,因為都是慢SQL。
通過SQL執行計劃,發現update_time範圍查詢最近一天的資料,掃描行數達到了上千萬,你說能不超時麼?
問題是之前都沒問題,突然就出了這個問題,是不是SQL寫錯了?其實沒有,只是因為update_time範圍內確實有這麼多資料。另一個問題來了,為什麼一天內有這麼多資料變更呢?
經排查,剛好有一個需求需要對老資料進行清洗,剛好update_time又是ON UPDATE CURRENT_TIMESTAMP,所以變更了的資料都會更新update_time,從而導致業務查詢異常。
解決方案一
以後凡是對於老資料清洗,除了更新要清洗的欄位之外,還需要更新update_time為原先的值,這樣就不會影響業務。
SQL如下:
update table set name=xxx,update_time=update_time where xxx=xxx
解決方案二
update_time如果加了ON UPDATE CURRENT_TIMESTAMP如果有業務查詢需求,就要慎重考慮是否可以使用,最好還是單純的作為資料的系統變更時間。業務變更時間還是由程式去控制,單獨加一個業務變更時間欄位,這樣即使清洗資料時update_time變了也不影響業務。