记录一些常用的SQL优化方式 和 mysqlsla 慢日志工具分析的基本操作,供自己复习
用到工具:
mysql-5.6.46
mysqlsla-2.03
navicat
Xshell
sql基本优化
添加索引
索引是必备的,不解释。
创建索引
create index index_name on table_name(列);
删除索引
DROP INDEX index_name ON table_name;
查看现有索引:
show index from 表;
explain命令
用于查看sql执行时是否使用了索引
语法:
explain 操作语句
explain详细参数说明:
参考 www.cnblogs.com/hailexuexi/…
www.cnblogs.com/linjiqin/p/…
查看索引使用情况
show status like 'Handler_read%';
Handler_read_key: 越高越好
Handler_read_rnd_next:越低越好
查询条件是否走索引的几种情况
- in走索引
- 模糊查询百分号在右边走索引,左右两侧都有或者左侧有都不走索引
- 范围查询走索引
- !=、<>、not null、is not null 这些反向条件都不走索引
- 条件计算或者调用函数不走索引,比如 where id/10=2 或者 where time<now()
- 使用 or 时 A or B 必须A和B两个字段都存在索引才会走索引
- 使用union\union all 代替or,有索引的就会使用索引。但是union使用了临时表,相对union all效率会差一些
- 字符串类型必须加引号才走索引
- order by 排序
(1)A和B都有索引,where A='1' order by A asc 是走索引的,如果去除条件A='1' 直接排序是不走索引的
(2)使用group by 进行分组统计时可以加上order by null,关闭排序功能 - exists 和 in 的用法:
一条sql,select * from A where id in(select a_id from B > 100)
当表A的数量大于表B数量时,使用in可减少查询时间。如果相同情况下使用exists则查询时间增加。
sql: select * from A where id exists(select a_id from B > 100)
两句 sql 分别执行 explain 可看出 rows 这一行数量 in 小于 exists,rows代表需要检查的行数,行数当然越少越好。 所以当表A的数量小于表B数量时,使用exists
一些查看mysql状态的操作
查看mysql版本
select version();
查看 mysql 的增删改查是以什么操作为主
show status like 'com_insert';
show status like 'com_delete';
show status like 'com_update';
show status like 'com_select';
这里记录了增删改查的次数,可以判断哪种操作居多
这里执行了一下 show status like 'com_select';
数据库启动运行的时间
show status like 'uptime';
数据库连接次数
show status like 'connections';
也可以查询全部状态(但是参数太多了我看不懂也记不住,淦!(╯°Д°)╯︵ ┻━┻)
show status;
查询事务提交和回滚次数
show status like 'com_commit';
show status like 'com_rollback';
mysql慢查询
慢查询相关变量
show variables like '%slow%';
慢查询的一些参数说明:
slow_query_log=off|on --------------是否开启慢查询日志
slow_query_log_file=filename -------指定保存路径及文件名,默认为数据文件目录,hostname-slow.log
long_query_time=10 ----------------指定多少秒返回查询的结果为慢查询
long-queries-not-using-indexe -----记录所有没有使用到索引的查询语句
min_examined_row_limit=1000------记录那些由于查找了多余1000次而引发的慢查询
long-slow-admin-statements--------记录那些慢的optimize table,analyze table和alter table语句
log-slow-Slave-statements-----------记录由Slave所产生的慢查询
也可以看看官网的说明:
mysql默认慢查询时间是10秒
show variables like 'long_query_time';
这里可以执行一句11秒的sql,然后查看一下执行了哪些慢查询
select sleep(11);
然后查询慢查询语句的次数:
show status like 'slow_queries';
觉得时间长可以改一下慢查询记录的时间:
改成3秒或者更短
set long_query_time = 3;
这属于临时设置,关闭连接之后会失效。最好在配置文件中修改
mysql的配置文件
文件位置在 /etc/my.cnf 中,慢查询的配置信息最好在配置文件中修改,然后重启mysql。
可以先查询文件的位置:
find / -name my.cnf
讲道理一般都在 /etc/my.cnf
编辑my.cnf文件,编辑之前先备份一下比较好:
vim /etc/my.cnf
如果编辑的时候出现swp文件可以按名字删除
rm -rf xxx.swp
切记:rm -rf 操作一定要加文件名,一定要加文件名,一定要加文件名。否则删库跑路不是梦。
按i 进入编辑模式
我这里用的是mysql 5.6.46 版本
查看mysql版本:
show variables like '%version%';
在[mysqld]下添加
---------------配置内容-----------------
#1表示开启 0表示关闭,也可以用ON\OFF
slow_query_log =1
#日志位置 (也自定义过其他路径,尝试了很多次,但是全部都失效,文件夹的所属也从root改成了mysql,并没有什么用。/var/lib/mysql 这个路径下可以成功写入慢查询信息,套个文件夹都会失败。没搞懂为什么,放弃。。)
slow_query_log_file=/var/lib/mysql/mysql-slow.log
#超过几秒加入慢查询记录
long_query_time=0.01
---------------配置内容-----------------
编辑完毕之后按Esc 退出 ,然后保存。
:q 不保存
:wq! 保存并退出
重启mysql:
service mysql restart
如果卡着不动,说明参数写错了位置或者是参数本身错误,所以要备份嘛~
使用 mysqlsla 分析慢查询日志
mysqlsla工具的作用:
自带的慢查询日志不太好看,体力活。这个工具是为了提取日志中的重点信息
自带的慢查询日志是这样的
用工具列出来的日志是这样的
mysqlsla下载和安装
一些操作的语法
指定数据库,提取查询最多的10条sql,直接展示 mysqlsla -lt slow -sort t_sum -sf "+select,update,INSERT" -db hard_db -top 10 /var/lib/mysql/mysql-slow.log
统计慢查询文件为/var/lib/mysql/mysql-slow.log 的数据库为mydata的所有select和update的慢查询sql,并查询次数最多的100条sql,并写到 sql_select_update.sql中去
mysqlsla -lt slow -sf "+select,update" -top 100 -sort c_sum -db mydata /var/lib/mysql/mysql-slow.log >/log/mysqlslalog/sql_select_update.log
查询记录最多的20个sql语句,并写到select.log中去 mysqlsla -lt slow --sort t_sum --top 20 /var/lib/mysql/mysql-slow.log >/log/mysqlslalog/select.log
统计慢查询文件为/var/lib/mysql/mysql-slow.log 的所有select的慢查询sql,并显示执行时间最长的100条sql,并写到 sql_select.log中去
mysqlsla -lt slow -sf "+select" -top 100 /var/lib/mysql/mysql-slow.log >/log/mysqlslalog/sql_select.log
分析出来的参数说明
Count--------------sql的执行次数及占总的slow log数量的百分比.
Time---------------执行时间, 包括总时间, 平均时间, 最小, 最大时间, 时间占到总慢sql时间的百分比.
Lock Time---------等待锁的时间.95% of Lock , 95%的慢sql等待锁时间.Rows sent, 结果行统计数量, 包括平均, 最小, 最大数量.
Rows examined---扫描的行数量.
Database----------属于哪个[数据库]
Users--------------哪个用户,IP, 占到所有用户执行的sql百分比
Query abstract----抽象后的sql语句
Query sample-----执行的sql语句
总结
这里只记录了最基本的Sql优化和慢查询日志分析,如果感觉有帮助,麻烦点个赞,注册个账户很麻烦吗?