SQL自動(dòng)審核-自助上線平臺(tái)
為了讓DBA從日常繁瑣的工作中解放出來(lái),通過(guò)SQL自助平臺(tái),可以讓開(kāi)發(fā)自上線,開(kāi)發(fā)提交SQL后就會(huì)自動(dòng)返回優(yōu)化建議,無(wú)需DBA的再次審核,從而提升上線效率,有利于建立數(shù)據(jù)庫(kù)開(kāi)發(fā)規(guī)范。
借鑒了去哪網(wǎng)Inception的思路并且把美團(tuán)網(wǎng)SQLAdvisor(索引優(yōu)化建議)集成在一起,并結(jié)合了之前寫(xiě)的《DBA的40條軍規(guī)》納入了審核規(guī)則里,用PHP實(shí)現(xiàn)。目前在我公司內(nèi)部使用。
SQL自動(dòng)審核主要完成兩方面目的:
1、避免性能太差的SQL進(jìn)入生產(chǎn)系統(tǒng),導(dǎo)致整體性能降低。
2、檢查開(kāi)發(fā)設(shè)計(jì)的索引是否合理,是否需要添加索引。
思路其實(shí)很簡(jiǎn)單:
1、獲取開(kāi)發(fā)提交的SQL
2、對(duì)要執(zhí)行的SQL做分析,觸碰事先定義好的規(guī)則來(lái)判斷這個(gè)SQL是否可以自動(dòng)審核通過(guò),未通過(guò)審核的需要人工處理。
下面是首頁(yè)界面:

使用說(shuō)明:
1、針對(duì)select/insert/update/create/alter加了規(guī)則,delete需要審批。
2、語(yǔ)句之間要有空格,例where id = 100,沒(méi)有空格會(huì)影響判斷的準(zhǔn)確性。
3、SQL語(yǔ)句后面要加分號(hào); MySQL解析器規(guī)定分號(hào)才可以執(zhí)行SQL。
4、反引號(hào)`可能會(huì)造成上線失敗,需要用文本編輯器替換掉。
5、支持多條SQL解析,用######六個(gè)井號(hào)分割。
- SELECT審核
1、開(kāi)發(fā)人員可以直接將SQL語(yǔ)句提交到平臺(tái)進(jìn)行風(fēng)險(xiǎn)評(píng)估
2、平臺(tái)對(duì)SQL語(yǔ)句進(jìn)行分析,自動(dòng)給出其不符合開(kāi)發(fā)規(guī)范的改進(jìn)意見(jiàn)
3、適用場(chǎng)景:應(yīng)用開(kāi)發(fā)階段
檢查項(xiàng):
1、select * 是否有必要查詢所有的字段?
2、警告!沒(méi)有where條件,注意where后面的字段要加上索引
3、沒(méi)有l(wèi)imit會(huì)查詢更多的數(shù)據(jù)
4、警告!子查詢性能低下,請(qǐng)轉(zhuǎn)為join表關(guān)聯(lián)
5、提示:in里面的數(shù)值不要超過(guò)1000個(gè)
6、提示:采用join關(guān)聯(lián),注意關(guān)聯(lián)字段要都加上索引,如on a.id=b.id
7、提示:MySQL對(duì)多表join關(guān)聯(lián)性能低下,建議不要超過(guò)3個(gè)表以上的關(guān)聯(lián)
8、警告!like '%%'雙百分號(hào)無(wú)法用到索引,like 'mysql%'這樣是可以利用到索引的
9、提示:默認(rèn)情況下,MySQL對(duì)所有GROUP BY col1,col2...的字段進(jìn)行排序。如果查詢包括GROUP BY,
想要避免排序結(jié)果的消耗,則可以指定ORDER BY NULL禁止排序。
10、警告!MySQL里用到order by rand()在數(shù)據(jù)量比較多的時(shí)候是很慢的,因?yàn)闀?huì)導(dǎo)致MySQL全表掃描,故也不會(huì)用到索引
11、提示:是否要加一個(gè)having過(guò)濾下?
12、警告!禁止不必要的order by排序,因?yàn)榍懊嬉呀?jīng)count統(tǒng)計(jì)了
13、警告!MySQL里不支持函數(shù)索引,例DATE_FORMAT('create_time','%Y-%m-%d')='2016-01-01'是無(wú)法用到索引的,需要改寫(xiě)為
create_time>='2016-01-01 00:00:00' and create_time<='2016-01-01 23:59:59'
之后會(huì)調(diào)用美團(tuán)網(wǎng)SQLAdvisor進(jìn)行索引檢查
使用概述:

1、選中你的數(shù)據(jù)庫(kù)名字
2、在對(duì)話框中輸入你要提交的SQL
3、點(diǎn)擊提交審核按鈕

提交以后,系統(tǒng)自動(dòng)返回SQL優(yōu)化改進(jìn)意見(jiàn)。
- insert審核
檢查項(xiàng):
1、警告: insert 表1 select 表2,會(huì)造成鎖表。

審核通過(guò)以后,會(huì)彈出用戶名和密碼,提示上線:

點(diǎn)擊我要上線按鈕,會(huì)調(diào)用MySQL客戶端進(jìn)行語(yǔ)法校驗(yàn)和表是否存在等校驗(yàn)。

- update審核
檢查項(xiàng):
1、警告!沒(méi)有where條件,update會(huì)全表更新,禁止執(zhí)行!!!
2、更新的行數(shù)小于10000行,可以由開(kāi)發(fā)自助執(zhí)行。否則請(qǐng)聯(lián)系DBA執(zhí)行!!!


防止where 1=1 繞過(guò)審核規(guī)則

必須寫(xiě)真實(shí)的where條件才可以執(zhí)行更新操作。
上線成功的SQL會(huì)記錄到一張操作日志表里,并且會(huì)把binlog位置點(diǎn)記錄下來(lái),方便日后的回滾操作。

- create審核
檢查項(xiàng):
1、警告!表沒(méi)有主鍵
2、警告!表主鍵應(yīng)該是自增的,缺少AUTO_INCREMENT
3、提示:id自增字段默認(rèn)值為1,auto_increment=1
4、警告!表沒(méi)有索引
5、警告!表中的索引數(shù)已經(jīng)超過(guò)5個(gè),索引是一把雙刃劍,它可以提高查詢效率但也會(huì)降低插入和更新的速度并占用磁盤(pán)空間
6、警告!表字段沒(méi)有中文注釋?zhuān)珻OMMENT應(yīng)該有默認(rèn)值,如COMMENT '姓名'
7、警告!表沒(méi)有中文注釋
8、警告!表缺少u(mài)tf8字符集,否則會(huì)出現(xiàn)亂碼
9、警告!表存儲(chǔ)引擎應(yīng)設(shè)置為InnoDB
10、警告!表應(yīng)該為timestamp類(lèi)型加默認(rèn)系統(tǒng)當(dāng)前時(shí)間


審核通過(guò)后,就可以上線了

上線失敗提示:

- alter審核
檢查項(xiàng):
1、警告!不支持create index語(yǔ)法,請(qǐng)更改為alter table add index語(yǔ)法。
2、警告!更改表結(jié)構(gòu)要減少與數(shù)據(jù)庫(kù)的交互次數(shù),應(yīng)改為,例alter table t1 add index IX_uid(uid),add index IX_name(name)
3、表記錄小于100萬(wàn)行,可以由開(kāi)發(fā)自助執(zhí)行。否則表太大請(qǐng)聯(lián)系DBA執(zhí)行!


數(shù)據(jù)庫(kù)上線工單查詢(只記錄成功執(zhí)行的SQL)
























