最近做的遊戲,上線後出了不少問題,所以我就經常去查資料庫資料,翻各種日誌等,但是在查詢的時候發現好蛋疼,有些地方的時間是寫 "2016-08-11 20:13:02"這種格式,有些地方的時間是寫 "1470917582000"這種格式,然後多張表資料進行對比的時候就很蛋疼,我得不停進行時間轉換,噁心得不行。最後實在忍不了,我要統一時間格式(由於時間都是單獨乙個字段記錄,所以比較好處理),兩種格式,很明顯,對於查資料來說,第一種格式更直觀,所以就決定了,將資料庫日誌類、郵件類的表的時間,統一成"2016-08-11 20:13:02"這種格式。
想了一下,沒法單純用mysql語句直轉換,於是就自己寫了乙個指令碼來轉換時間格式(新增的很好處理,主要問題是要將之前記錄的資料轉換一次,在伺服器維護的時候,進行處理)。
一開始想法很簡單(很少用mysql,使用的時候也都是簡單使用而已),就是把資料庫資料全部select出來,然後一條條update,本地測試,沒啥問題。後面就把外網的玩家部分資料匯入進來,進行測試。不導不知道,一導嚇一跳,記憶體爆了,哈哈,外網資料量太大,根本就沒法讓我一下子全select出來。那咋辦呢,想了一下,其實我並不需要那麼多資料,對每條記錄,我只要select出key和time就行了,說幹就幹,試了一下,好像不會爆了,但是發現他的執行速度超級慢,一百萬條記錄,跑了五六個小時,這還只是部分資料啊,要是是全部資料,那得跑多久啊,停服維護這麼久,還不被罵死。沒辦法,那就優化吧。
首先想到的是,一條一條更新的速度太慢了,然後就想批量更新,一次更新n條資料。實踐是檢驗真理的唯一標準,不一會兒,**就敲完了,重新試了一下,效果依舊不理想。啊哦,真是要崩潰!後面又想到了利用非同步,我一下子開多個mysql連線,同時處理,可是依舊慢的一筆。然後就放棄了,更新的效率肯定是滿足不了了。然後就想著繞彎子了,我新建一張表,把舊表資料取出來,處理完後,直接插入到新錶,然後再把舊表刪除,把新錶重新命名成舊表的名字。想想,insert into的速度應該會比update快不少。但是要把舊表資料全部取出來,記憶體會爆掉,所以我就用慢慢取的方式, select+limit。試了一下,速度快了不少,但是感覺也得跑個乙個多小時。雖然快了很多,但是這速度肯定還是不行。
然後試了下,select的時候用select + where + order by + limit的方法,where和order by都是用time去處理,跑了一下,十來分鐘就搞定了。後面想想,where和order by的時候用表的主鍵去處理,應該會快點,然後就試了一下,哇塞,效果很明顯,select + where + order by + limit的方法(用主鍵去處理where 和order by) ,一分鐘就處理完了所有資料。取一次資料,處理完資料後,插入一次資料,可以根據自己的資料量大小,適當調整一次要select多少條資料出來。記住,select出來後,處理完,一次性插入新錶,不要一條條插入!
最終結果,用select + where + order by + limit的方法(用主鍵去處理where 和order by) ,一分鐘左右就處理完了五百萬條左右的資料,有好幾張表,其中有兩張表都各有一兩百萬條的資料,而最初的那種逐條update的方法,預計得十個小時以上。雖然幾經波折,最後終於放心地交差了。
重點:普通的select方式取出來速度很慢,插入新錶的方案,效能的關鍵點在於從舊表select出資料,至於插入,只要使用批量插入就好啦!
小插曲: 建立新錶的時候,我是用複製舊表結構的方式去建立的,複製舊表結構的時候,記得使用create table newtablename like oldtablename的方式,不然會沒有把舊表的索引複製過來
Mysql批量插入更新效能優化
對於資料量較大的插入和更新,因io cpu等效能瓶頸,會產生大量的時間消耗,目前主流的優化主要包括預編譯 單條sql插入多條資料 事務插入等,下面詳細介紹一下 單條插入 mybatis insert into sys city city code,city name,province name,al...
Mysql更新效能優化 MySQL效能優化
效能優化是通過某些有效的方法來提高mysql的執行速度,減少占用的磁碟空間。效能優化包含很多方面,例如優化查詢速度,優化更新速度和優化mysql伺服器等。本文介紹方法的主要有 優化查詢 優化資料庫結構 優化mysql伺服器 資料庫管理人員可以使用show status語句來查詢mysql資料庫的效能...
MySQL 批量更新資料
最近做的乙個專案有這個乙個需求,就是記錄每個訊息的檢視數。規則是只要客戶端呼叫訊息列表,就把當前介面返回的資料對應的資料庫裡面的檢視欄位 1。做的是後端給前端一次返回20條資料,那麼就存在,後端需要一次跟新這20條記錄的檢視數。這就是設計到mysql的批量更新操作了。訊息表message idcon...