天天看點

線上業務kill SQL一系列想法

寫了一個存儲過程為玩家發送獎勵,MySQL5.0

    在本地測試文法沒有問題,但線上上運作十分緩慢,show processlist ,status顯示 sending data;可初步判斷語句未使用索引。由于執行太慢,我們選擇kill 掉了該語句。

    設計到的語句部分:select ... from p join a ON  p.pid=a.gameid=1428;explain type 顯示 all 即全表掃描;(pid和gameid 都是含有索引的);按道理來說不應該是全表掃描,初步懷疑是利用索引的成本(CBO)太大,MySQL才選擇了全表掃描;但這一的解釋也是不合理的。pid和gameid都是唯一的。及表中索引的基數還是很大的。修改語句為:select ... from p join a ON  p.pid=a.gameid and p.pid=1428; explain type顯示為a表為all,p表為const;執行速度提高百倍。

    小結:select查詢共有3個過濾器,on、where、having,on是最先執行的過濾過程。應該講多個條件依次寫出,不要寫出三個選項作為一個過濾條件,即不要出現:p.pid=a.gameid=1428 應該為p.pid=a.gameid and p.pid=1428(這個算不算MySQL 5.0的bug 呢?)

    由于是多區多服DB批量執行該腳本。再次執行腳本的時候造成部分玩家收到雙份獎勵,這個可以通過臨時表中進行記錄,并及時更新到正确狀态。關鍵是如何更好的更好的減少出錯:

    小結:對于線上更新語句,線上必須有足夠多的資料進行測試;

          批量執行過程遇到截斷或停止(人為或突發情況),截斷的時候要考慮到DBA是否能承受錯誤資料的壓力;對于突發情況終止,進行操作行為記錄,具體行為資料前後變化狀态等。

本文轉自 位鵬飛 51CTO部落格,原文連結:http://blog.51cto.com/weipengfei/1192569,如需轉載請自行聯系原作者