溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

SQLAdvisor美團(tuán)SQL索引優(yōu)化建議工具

發(fā)布時間:2020-06-16 13:16:52 來源:網(wǎng)絡(luò) 閱讀:7290 作者:dbapower 欄目:數(shù)據(jù)庫

SQLAdvisor美團(tuán)SQL索引優(yōu)化建議工具

SQLAdvisor美團(tuán)SQL索引優(yōu)化建議工具

前言

Part1:寫在最前

SQLAdvisor是美團(tuán)開源的一款SQL索引優(yōu)化建議工具,是由美團(tuán)點評公司技術(shù)工程部DBA團(tuán)隊(北京)開發(fā)維護(hù)的一個分析SQL給出索引優(yōu)化建議的工具。它基于MySQL原生態(tài)詞法解析,結(jié)合分析SQL中的where條件、聚合條件、多表Join關(guān)系 給出索引優(yōu)化建議。目前SQLAdvisor在美團(tuán)點評內(nèi)部廣泛應(yīng)用,公司內(nèi)部對SQLAdvisor的開發(fā)全面轉(zhuǎn)到github上,開源和內(nèi)部使用保持一致。本文記錄對該工具的初步安裝和基本使用。


安裝

Part1:構(gòu)建安裝環(huán)境

[root@HE3 ~]# yum install git

[root@HE3 ~]# git clone https://github.com/Meituan-Dianping/SQLAdvisor.git

[root@HE3 ~]# yum install cmake libaio-devel libffi-devel glib2 glib2-devel

[root@HE3 ~]# yum install http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm

[root@HE3 ~]# yum install Percona-Server-shared-56

[root@HE3 lib64]# cd /usr/lib64/

[root@HE3 ~]# ln -s libperconaserverclient_r.so.18 libperconaserverclient_r.so


Warning:告1

這里該命令一直過不去yum install --enablerepo=Percona56 Percona-Server-shared-56,后直接安裝的Percona-Server-shared-56通過

Warning:告2

跟據(jù)glib安裝的路徑,修改SQLAdvisor/sqladvisor/CMakeLists.txt中的兩處include_directories針對glib設(shè)置的path。本文采用yum安裝的git,故glib yum 安裝默認(rèn)不需要修改路徑

Warning:告3

編譯sqladvisor時依賴perconaserverclient_r, 因此需要安裝Percona-Server-shared-56。有可能需要配置軟鏈接例如:1. cd /usr/lib64/ 2. ln -s libperconaserverclient_r.so.18 libperconaserverclient_r.so

Warning:告4

有可能需要配置percona56 yum源: yum install http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm


[root@HE3 ~]#cmake -DBUILD_CONFIG=mysql_release -DCMAKE_BUILD_TYPE=debug -DCMAKE_INSTALL_PREFIX=/usr/local/sqlparser ./

[root@HE3 ~]# make && make install

[root@HE3 ~]# cd SQLAdvisor/sqladvisor

[root@HE3 sqladvisor]# cmake -DCMAKE_BUILD_TYPE=debug ./

[root@HE3 sqladvisor]# make

在本路徑下生成一個sqladvisor可執(zhí)行文件,這即是我們想要的。


使用

Part1:對小表進(jìn)行測試

[root@HE3 sqladvisor]# ./sqladvisor -h 127.0.0.1 -P 3306 -u root -p "MANAGER" -d helei1 -q "select * from helei1" -v 1

2017-03-21 20:37:53 8581 [Note] 第1步: 對SQL解析優(yōu)化之后得到的SQL:select `*` AS `*` from `helei1`.`helei1` 

2017-03-21 20:37:53 8581 [Note] 第2步:表helei1 的SQL太逆天,沒有優(yōu)化建議 

2017-03-21 20:37:53 8581 [Note] 第3步: SQLAdvisor結(jié)束! 



Part2:對大表進(jìn)行測試(有索引)

這里我們對表helei進(jìn)行分析,改表在c1列上存在索引

[root@HE3 sqladvisor]# ./sqladvisor -h 127.0.0.1 -P 3306 -u root -p "MANAGER" -d helei1 -q "explain select * from helei where c1=88501;" -v 1

2017-03-21 21:19:23 8624 [Note] 第1步: 對SQL解析優(yōu)化之后得到的SQL:select `*` AS `*` from `helei1`.`helei` where (`c1` = 88501) 

2017-03-21 21:19:23 8624 [Note] 第2步:開始解析where中的條件:(`c1` = 88501) 

2017-03-21 21:19:23 8624 [Note] show index from helei 

2017-03-21 21:19:23 8624 [Note] show table status like 'helei' 

2017-03-21 21:19:23 8624 [Note] select count(*) from ( select `c1` from `helei` FORCE INDEX( PRIMARY ) order by id DESC limit 10000) `helei` where (`c1` = 88501)  

2017-03-21 21:19:23 8624 [Note] 第3步:表helei的行數(shù):200380,limit行數(shù):10000,得到where條件中(`c1` = 88501)的選擇度:10000 

2017-03-21 21:19:23 8624 [Note] 第4步:開始驗證 字段c1是不是主鍵。表名:helei 

2017-03-21 21:19:23 8624 [Note] show index from helei where Key_name = 'PRIMARY' and Column_name ='c1' and Seq_in_index = 1 

2017-03-21 21:19:23 8624 [Note] 第5步:字段c1不是主鍵。表名:helei 

2017-03-21 21:19:23 8624 [Note] 第6步:開始驗證 字段c1是不是主鍵。表名:helei 

2017-03-21 21:19:23 8624 [Note] show index from helei where Key_name = 'PRIMARY' and Column_name ='c1' and Seq_in_index = 1 

2017-03-21 21:19:23 8624 [Note] 第7步:字段c1不是主鍵。表名:helei 

2017-03-21 21:19:23 8624 [Note] 第8步:開始驗證表中是否已存在相關(guān)索引。表名:helei, 字段名:c1, 在索引中的位置:1 

2017-03-21 21:19:23 8624 [Note] show index from helei where Column_name ='c1' and Seq_in_index =1 

2017-03-21 21:19:23 8624 [Note] 第9步:索引(c1)已存在 

2017-03-21 21:19:23 8624 [Note] 第10步: SQLAdvisor結(jié)束! 


可以看到,最后給出了該條SQL已經(jīng)擁有有效索引的建議


Part2:對大表進(jìn)行測試(無索引)

這里我們對表helei進(jìn)行分析,改表在c5列上沒有索引

[root@HE3 sqladvisor]# ./sqladvisor -h 127.0.0.1 -P 3306 -u root -p "MANAGER" -d helei1 -q "explain select * from helei where c5=74685;" -v 1

2017-03-21 21:20:53 8628 [Note] 第1步: 對SQL解析優(yōu)化之后得到的SQL:select `*` AS `*` from `helei1`.`helei` where (`c5` = 74685) 

2017-03-21 21:20:53 8628 [Note] 第2步:開始解析where中的條件:(`c5` = 74685) 

2017-03-21 21:20:53 8628 [Note] show index from helei 

2017-03-21 21:20:53 8628 [Note] show table status like 'helei' 

2017-03-21 21:20:53 8628 [Note] select count(*) from ( select `c5` from `helei` FORCE INDEX( PRIMARY ) order by id DESC limit 10000) `helei` where (`c5` = 74685)  

2017-03-21 21:20:53 8628 [Note] 第3步:表helei的行數(shù):201361,limit行數(shù):10000,得到where條件中(`c5` = 74685)的選擇度:10000 

2017-03-21 21:20:53 8628 [Note] 第4步:開始驗證 字段c5是不是主鍵。表名:helei 

2017-03-21 21:20:53 8628 [Note] show index from helei where Key_name = 'PRIMARY' and Column_name ='c5' and Seq_in_index = 1 

2017-03-21 21:20:53 8628 [Note] 第5步:字段c5不是主鍵。表名:helei 

2017-03-21 21:20:53 8628 [Note] 第6步:開始驗證 字段c5是不是主鍵。表名:helei 

2017-03-21 21:20:53 8628 [Note] show index from helei where Key_name = 'PRIMARY' and Column_name ='c5' and Seq_in_index = 1 

2017-03-21 21:20:53 8628 [Note] 第7步:字段c5不是主鍵。表名:helei 

2017-03-21 21:20:53 8628 [Note] 第8步:開始驗證表中是否已存在相關(guān)索引。表名:helei, 字段名:c5, 在索引中的位置:1 

2017-03-21 21:20:53 8628 [Note] show index from helei where Column_name ='c5' and Seq_in_index =1 

2017-03-21 21:20:53 8628 [Note] 第9步:開始輸出表helei索引優(yōu)化建議: 

2017-03-21 21:20:53 8628 [Note] Create_Index_SQL:alter table helei add index idx_c5(c5) 

2017-03-21 21:20:53 8628 [Note] 第10步: SQLAdvisor結(jié)束!


可以看到,最后給出了創(chuàng)建索引的建議



Part3:多條SQL同時分析

可以創(chuàng)建任意名的參數(shù)文件,這里叫helei.cnf,輸入常規(guī)的數(shù)據(jù)庫連接信息和SQL,SQL之間用分號隔開。

[root@HE3 sqladvisor]# cat helei.cnf 

[sqladvisor]

username=root

password=MANAGER

host=127.0.0.1

port=3306

dbname=helei1

sqls=select * from helei where c1=88501;select * from helei where c5=74685;


這里使用-f命令來載入helei.cnf中的配置

[root@HE3 sqladvisor]# ./sqladvisor -f helei.cnf -v 1

2017-03-21 21:27:35 8640 [Note] 第1步: 對SQL解析優(yōu)化之后得到的SQL:select `*` AS `*` from `helei1`.`helei` where (`c1` = 88501) 

2017-03-21 21:27:35 8640 [Note] 第2步:開始解析where中的條件:(`c1` = 88501) 

2017-03-21 21:27:35 8640 [Note] show index from helei 

2017-03-21 21:27:35 8640 [Note] show table status like 'helei' 

2017-03-21 21:27:35 8640 [Note] select count(*) from ( select `c1` from `helei` FORCE INDEX( PRIMARY ) order by id DESC limit 10000) `helei` where (`c1` = 88501)  

2017-03-21 21:27:35 8640 [Note] 第3步:表helei的行數(shù):200674,limit行數(shù):10000,得到where條件中(`c1` = 88501)的選擇度:10000 

2017-03-21 21:27:35 8640 [Note] 第4步:開始驗證 字段c1是不是主鍵。表名:helei 

2017-03-21 21:27:35 8640 [Note] show index from helei where Key_name = 'PRIMARY' and Column_name ='c1' and Seq_in_index = 1 

2017-03-21 21:27:35 8640 [Note] 第5步:字段c1不是主鍵。表名:helei 

2017-03-21 21:27:35 8640 [Note] 第6步:開始驗證 字段c1是不是主鍵。表名:helei 

2017-03-21 21:27:35 8640 [Note] show index from helei where Key_name = 'PRIMARY' and Column_name ='c1' and Seq_in_index = 1 

2017-03-21 21:27:35 8640 [Note] 第7步:字段c1不是主鍵。表名:helei 

2017-03-21 21:27:35 8640 [Note] 第8步:開始驗證表中是否已存在相關(guān)索引。表名:helei, 字段名:c1, 在索引中的位置:1 

2017-03-21 21:27:35 8640 [Note] show index from helei where Column_name ='c1' and Seq_in_index =1 

2017-03-21 21:27:35 8640 [Note] 第9步:索引(c1)已存在 

2017-03-21 21:27:35 8640 [Note] 第10步: SQLAdvisor結(jié)束! 

2017-03-21 21:27:35 8640 [Note] 第1步: 對SQL解析優(yōu)化之后得到的SQL:select `*` AS `*` from `helei1`.`helei` where (`c5` = 74685) 

2017-03-21 21:27:35 8640 [Note] 第2步:開始解析where中的條件:(`c5` = 74685) 

2017-03-21 21:27:35 8640 [Note] show index from helei 

2017-03-21 21:27:35 8640 [Note] show table status like 'helei' 

2017-03-21 21:27:35 8640 [Note] select count(*) from ( select `c5` from `helei` FORCE INDEX( PRIMARY ) order by id DESC limit 10000) `helei` where (`c5` = 74685)  

2017-03-21 21:27:35 8640 [Note] 第3步:表helei的行數(shù):201067,limit行數(shù):10000,得到where條件中(`c5` = 74685)的選擇度:10000 

2017-03-21 21:27:35 8640 [Note] 第4步:開始驗證 字段c5是不是主鍵。表名:helei 

2017-03-21 21:27:35 8640 [Note] show index from helei where Key_name = 'PRIMARY' and Column_name ='c5' and Seq_in_index = 1 

2017-03-21 21:27:35 8640 [Note] 第5步:字段c5不是主鍵。表名:helei 

2017-03-21 21:27:35 8640 [Note] 第6步:開始驗證 字段c5是不是主鍵。表名:helei 

2017-03-21 21:27:35 8640 [Note] show index from helei where Key_name = 'PRIMARY' and Column_name ='c5' and Seq_in_index = 1 

2017-03-21 21:27:35 8640 [Note] 第7步:字段c5不是主鍵。表名:helei 

2017-03-21 21:27:35 8640 [Note] 第8步:開始驗證表中是否已存在相關(guān)索引。表名:helei, 字段名:c5, 在索引中的位置:1 

2017-03-21 21:27:35 8640 [Note] show index from helei where Column_name ='c5' and Seq_in_index =1 

2017-03-21 21:27:35 8640 [Note] 第9步:開始輸出表helei索引優(yōu)化建議: 

2017-03-21 21:27:35 8640 [Note] Create_Index_SQL:alter table helei add index idx_c5(c5) 

2017-03-21 21:27:35 8640 [Note] 第10步: SQLAdvisor結(jié)束! 


可以看到這里對helei.cnf中的兩個SQL進(jìn)行了一次性建議輸出。


Warning:告5

  • SQL中的子查詢、or條件、使用函數(shù)的條件 會忽略不處理。

  • 命令行傳入sql參數(shù)時,注意sql中的雙引號、反引號 都需要用\轉(zhuǎn)義。建議使用配置文件形式調(diào)用


——總結(jié)——

可以看出,SQLAdvisor對查詢SQL給出了索引創(chuàng)建的優(yōu)化和建議,還是不錯的,后續(xù)會進(jìn)一步進(jìn)行深度測試。由于筆者的水平有限,編寫時間也很倉促,文中難免會出現(xiàn)一些錯誤或者不準(zhǔn)確的地方,不妥之處懇請讀者批評指正。



參考:https://github.com/Meituan-Dianping/SQLAdvisor/blob/master/doc/QUICK_START.md

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI