1. 程式人生 > >SQL索引優化工具SQLAdvisor介紹

SQL索引優化工具SQLAdvisor介紹

--help sel join 想要 uniq limit OS pri git

SQLAdvisor是美團開源的一款SQL索引優化建議工具,是由美團點評公司技術工程部DBA團隊(北京)開發維護的一個分析SQL給出索引優化建議的工具。它基於MySQL原生態詞法解析,結合分析SQL中的where條件、聚合條件、多表Join關系 給出索引優化建議。目前SQLAdvisor在美團點評內部廣泛應用,公司內部對SQLAdvisor的開發全面轉到github上,開源和內部使用保持一致。

博文記錄對該工具的初步安裝和基本使用

一、軟件的安裝部署

[admin@git-server opt]# pwd
/opt
[admin@git-server opt]#  yum install git
[admin@git-server opt]# git clone https://github.com/Meituan-Dianping/SQLAdvisor.git
[admin@git-server opt]# yum install cmake libaio-devel libffi-devel glib2 glib2-devel
[admin@git-server opt]# yum install http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm
[admin@git-server opt]# yum install Percona-Server-shared-56
[admin@git-server opt]# cd /usr/lib64/
[admin@git-server opt]# ln -s libperconaserverclient_r.so.18 libperconaserverclient_r.so

[admin@git-server opt]# cmake -DBUILD_CONFIG=mysql_release -DCMAKE_BUILD_TYPE=debug -DCMAKE_INSTALL_PREFIX=/usr/local/sqlparser ./
[admin@git-server opt]# make && make install
[admin@git-server opt]# cd SQLAdvisor/sqladvisor
[admin@git-server sqladvisor]# cmake -DCMAKE_BUILD_TYPE=debug ./
[admin@git-server sqladvisor]# make

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

命令參數如下:

[admin@git-server sqladvisor]# ./sqladvisor --help
Usage:
  sqladvisor [OPTION...] sqladvisor

SQL Advisor Summary

Help Options:
  -?, --help              Show help options

Application Options:
  -f, --defaults-file     sqls file
  -u, --username          username
  -p, --password          password
  -P, --port              port
  -h, --host              host
  -d, --dbname            database name
  -q, --sqls              sqls
  -v, --verbose           1:output logs 0:output nothing

二、測試

測試一:對小表進行測試

[admin@git-server sqladvisor]#  ./sqladvisor -h 127.0.0.1 -P 3306 -u admin -p "test@6666" -d zixun3 -q "select * from  zx_addonarticle;" -v 1
2018-06-14 17:57:33 1050 [Note] 第1步: 對SQL解析優化之後得到的SQL:select `*` AS `*` from `zixun3`.`zx_addonarticle` 

2018-06-14 17:57:33 1050 [Note] 第2步:表zx_addonarticle 的SQL太逆天,沒有優化建議 

2018-06-14 17:57:33 1050 [Note] 第3步: SQLAdvisor結束! 

當然上面的命令也是可以寫入配置文件,通過-f參數指定文件來操作的

[admin@git-server sqladvisor]# cat test01.cnf 
[sqladvisor]
username=admin
password=test@6666
host=127.0.0.1
port=3306
dbname=zixun3
sqls=select * from  zx_addonarticle;
[admin@git-server sqladvisor]# ./sqladvisor -f test01.cnf -v 1
2018-06-14 18:01:42 1198 [Note] 第1步: 對SQL解析優化之後得到的SQL:select `*` AS `*` from `zixun3`.`zx_addonarticle` 
2018-06-14 18:01:42 1198 [Note] 第2步:表zx_addonarticle 的SQL太逆天,沒有優化建議 
2018-06-14 18:01:42 1198 [Note] 第3步: SQLAdvisor結束! 

測試二:對大表有索引測試

MySQL [zhangyou]> show index from test_table01;;
+--------------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table        | Non_unique | Key_name    | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test_table01 |          0 | PRIMARY     |            1 | id          | A         |      120201 |     NULL | NULL   |      | BTREE      |         |               |
| test_table01 |          0 | day         |            1 | day         | A         |          10 |     NULL | NULL   |      | BTREE      |         |               |
| test_table01 |          0 | day         |            2 | planid      | A         |        1521 |     NULL | NULL   |      | BTREE      |         |               |
| test_table01 |          0 | day         |            3 | uid         | A         |      120201 |     NULL | NULL   |      | BTREE      |         |               |
| test_table01 |          0 | day         |            4 | siteid      | A         |      120201 |     NULL | NULL   |      | BTREE      |         |               |
| test_table01 |          0 | day         |            5 | zoneid      | A         |      120201 |     NULL | NULL   |      | BTREE      |         |               |
| test_table01 |          1 | idx_day_uid |            1 | day         | A         |         112 |     NULL | NULL   |      | BTREE      |         |               |
| test_table01 |          1 | idx_day_uid |            2 | uid         | A         |       10927 |     NULL | NULL   |      | BTREE      |         |               |
+--------------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
11 rows in set (0.00 sec)
[admin@git-server sqladvisor]# vim test.cnf 
[sqladvisor]
username=admin
password=test@6666
host=127.0.0.1
port=3306
dbname=zhangyou
sqls=select * from test_table01 where day=‘2016-04-22‘ and uid=26‘;
[admin@git-server sqladvisor]# ./sqladvisor -f test.cnf -v 1
2018-06-14 18:08:24 1281 [Note] 第1步: 對SQL解析優化之後得到的SQL:select had some error 
2018-06-14 18:08:24 1281 [Note] 第2步:開始解析where中的條件:(`day` = ‘2016-04-22‘) 
2018-06-14 18:08:24 1281 [Note] show index from test_table01 
2018-06-14 18:08:24 1281 [Note] show table status like ‘test_table01‘ 
2018-06-14 18:08:24 1281 [Note] select count(*) from ( select `day` from `test_table01` FORCE INDEX( day ) order by day DESC,planid DESC,uid DESC,siteid DESC,zoneid DESC,adstypeid DESC limit 10000) `test_table01` where (`day` = ‘2016-04-22‘)  
2018-06-14 18:08:24 1281 [Note] 第3步:表test_table01的行數:120201,limit行數:10000,得到where條件中(`day` = ‘2016-04-22‘)的選擇度:10000 
2018-06-14 18:08:24 1281 [Note] 第4步:開始解析where中的條件:(`uid` = 26) 
2018-06-14 18:08:24 1281 [Note] show index from test_table01 
2018-06-14 18:08:24 1281 [Note] show table status like ‘test_table01‘ 
2018-06-14 18:08:24 1281 [Note] select count(*) from ( select `uid` from `test_table01` FORCE INDEX( day ) order by day DESC,planid DESC,uid DESC,siteid DESC,zoneid DESC,adstypeid DESC limit 10000) `test_table01` where (`uid` = 26)  
2018-06-14 18:08:24 1281 [Note] 第5步:表test_table01的行數:120201,limit行數:10000,得到where條件中(`uid` = 26)的選擇度:10000 
2018-06-14 18:08:24 1281 [Note] 第6步:開始驗證 字段day是不是主鍵。表名:test_table01 
2018-06-14 18:08:24 1281 [Note] show index from test_table01 where Key_name = ‘PRIMARY‘ and Column_name =‘day‘ and Seq_in_index = 1 
2018-06-14 18:08:24 1281 [Note] 第7步:字段day不是主鍵。表名:test_table01 
2018-06-14 18:08:24 1281 [Note] 第8步:開始驗證 字段day是不是主鍵。表名:test_table01 
2018-06-14 18:08:24 1281 [Note] show index from test_table01 where Key_name = ‘PRIMARY‘ and Column_name =‘day‘ and Seq_in_index = 1 
2018-06-14 18:08:24 1281 [Note] 第9步:字段day不是主鍵。表名:test_table01 
2018-06-14 18:08:24 1281 [Note] 第10步:開始驗證表中是否已存在相關索引。表名:test_table01, 字段名:day, 在索引中的位置:1 
2018-06-14 18:08:24 1281 [Note] show index from test_table01 where Column_name =‘day‘ and Seq_in_index =1 
2018-06-14 18:08:24 1281 [Note] 第11步:開始驗證 字段uid是不是主鍵。表名:test_table01 
2018-06-14 18:08:24 1281 [Note] show index from test_table01 where Key_name = ‘PRIMARY‘ and Column_name =‘uid‘ and Seq_in_index = 1 
2018-06-14 18:08:24 1281 [Note] 第12步:字段uid不是主鍵。表名:test_table01 
2018-06-14 18:08:24 1281 [Note] 第13步:開始驗證表中是否已存在相關索引。表名:test_table01, 字段名:uid, 在索引中的位置:2 
2018-06-14 18:08:24 1281 [Note] show index from test_table01 where Column_name =‘uid‘ and Seq_in_index =2 
2018-06-14 18:08:24 1281 [Note] 第14步:索引(day,uid)已存在 
2018-06-14 18:08:24 1281 [Note] 第15步: SQLAdvisor結束! 

測試三:對大表無索引進行測試

[admin@git-server sqladvisor]# vim test.cnf 
[sqladvisor]
username=admin
password=test@6666
host=127.0.0.1
port=3306
dbname=zhangyou
sqls=select * from test_table01 where  zoneid=42 and views=198;
[admin@git-server sqladvisor]# ./sqladvisor -f test.cnf -v 1
2018-06-14 18:15:09 1348 [Note] 第1步: 對SQL解析優化之後得到的SQL:select `*` AS `*` from `zhangyou`.`test_table01` where ((`zoneid` = 42) and (`views` = 198)) 
2018-06-14 18:15:09 1348 [Note] 第2步:開始解析where中的條件:(`zoneid` = 42) 
2018-06-14 18:15:09 1348 [Note] show index from test_table01 
2018-06-14 18:15:09 1348 [Note] show table status like ‘test_table01‘ 
2018-06-14 18:15:09 1348 [Note] select count(*) from ( select `zoneid` from `test_table01` FORCE INDEX( day ) order by day DESC,planid DESC,uid DESC,siteid DESC,zoneid DESC,adstypeid DESC limit 10000) `test_table01` where (`zoneid` = 42)  
2018-06-14 18:15:09 1348 [Note] 第3步:表test_table01的行數:120201,limit行數:10000,得到where條件中(`zoneid` = 42)的選擇度:10000 
2018-06-14 18:15:09 1348 [Note] 第4步:開始解析where中的條件:(`views` = 198) 
2018-06-14 18:15:09 1348 [Note] show index from test_table01 
2018-06-14 18:15:09 1348 [Note] show table status like ‘test_table01‘ 
2018-06-14 18:15:09 1348 [Note] select count(*) from ( select `views` from `test_table01` FORCE INDEX( day ) order by day DESC,planid DESC,uid DESC,siteid DESC,zoneid DESC,adstypeid DESC limit 10000) `test_table01` where (`views` = 198)  
2018-06-14 18:15:09 1348 [Note] 第5步:表test_table01的行數:120201,limit行數:10000,得到where條件中(`views` = 198)的選擇度:2000 
2018-06-14 18:15:09 1348 [Note] 第6步:開始驗證 字段zoneid是不是主鍵。表名:test_table01 
2018-06-14 18:15:09 1348 [Note] show index from test_table01 where Key_name = ‘PRIMARY‘ and Column_name =‘zoneid‘ and Seq_in_index = 1 
2018-06-14 18:15:09 1348 [Note] 第7步:字段zoneid不是主鍵。表名:test_table01 
2018-06-14 18:15:09 1348 [Note] 第8步:開始驗證 字段zoneid是不是主鍵。表名:test_table01 
2018-06-14 18:15:09 1348 [Note] show index from test_table01 where Key_name = ‘PRIMARY‘ and Column_name =‘zoneid‘ and Seq_in_index = 1 
2018-06-14 18:15:09 1348 [Note] 第9步:字段zoneid不是主鍵。表名:test_table01 
2018-06-14 18:15:09 1348 [Note] 第10步:開始驗證表中是否已存在相關索引。表名:test_table01, 字段名:zoneid, 在索引中的位置:1 
2018-06-14 18:15:09 1348 [Note] show index from test_table01 where Column_name =‘zoneid‘ and Seq_in_index =1 
2018-06-14 18:15:09 1348 [Note] 第11步:開始驗證 字段views是不是主鍵。表名:test_table01 
2018-06-14 18:15:09 1348 [Note] show index from test_table01 where Key_name = ‘PRIMARY‘ and Column_name =‘views‘ and Seq_in_index = 1 
2018-06-14 18:15:09 1348 [Note] 第12步:字段views不是主鍵。表名:test_table01 
2018-06-14 18:15:09 1348 [Note] 第13步:開始驗證表中是否已存在相關索引。表名:test_table01, 字段名:views, 在索引中的位置:2 
2018-06-14 18:15:09 1348 [Note] show index from test_table01 where Column_name =‘views‘ and Seq_in_index =2 
2018-06-14 18:15:09 1348 [Note] 第14步:開始輸出表test_table01索引優化建議: 
~~*2018-06-14 18:15:09 1348 [Note] CreateIndexSQL:alter table testtable01 add index idxzoneidviews(zoneid,views) *~~
2018-06-14 18:15:09 1348 [Note] 第15步: SQLAdvisor結束! 

可以看到,最後給出了創建索引的建議

測試四:多條SQL同時分析:

[admin@git-server sqladvisor]# cat /opt/SQLAdvisor/sqladvisor/test.cnf 
[sqladvisor]
username=admin
password=test@6666
host=127.0.0.1
port=3306
dbname=zhangyou
sqls=select * from test_table01 where  zoneid=42 and views=198;select * from test_table01 where day=‘2016-04-22‘ and uid=26‘;
[admin@git-server sqladvisor]# 

參考博文地址:http://blog.51cto.com/suifu/1909169

SQL索引優化工具SQLAdvisor介紹