SQL语句优化
1)优化SQL语句的一般步骤
1. 查询日志找出耗时高的SQL
2. EXPLAIN查看索引是否生效
3. 查看表索引是否生效
2)索引优化
3)check与optimize使用方法
4)常用SQL的优化
检查服务器增、删、改和查的使用频次:(本次启动以来)
通过show status命令了解各种SQL的执行频率。
格式:mysql>show [session|global] status;
其中:session(默认)表示当前连接,global表示自数据库其中至今
show status like "%Com_update%";
show status like "%Com_insert%";
show status like "%Com_select%";
show status like "%Com_delete%";
查innodb自启动以来的影响行数:
mysql> show status like "%InnoDB_rows%";
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| Innodb_rows_deleted | 2 |
| Innodb_rows_inserted | 0 |
| Innodb_rows_read | 105 |
| Innodb_rows_updated | 3 |
+----------------------+-------+
定位执行效率较低的SQL语句:
查看user表索引
索引参考文档:
http://c.biancheng.net/view/7364.html
show index from user\G
让测试数据成倍增长
insert into user(name,age,score,created_at,updated_at) select name,age,score,created_at,updated_at from user;
1.explain(常用)或desc定位一条sql语句的影响行数
前提是已经查询到该sql语句花费了大量的时间,执行效率慢的情况,超过了1ms等等
explain使用查考文档:https://www.jianshu.com/p/18ab39d8dd88
mysql>explain select * from user where username='user8'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: user
partitions: NULL //
type: ALL //联合查询所使用的类型,type显示的是访问类型,是较为重要的一个指标,结果值从好到坏依次是:
system > const > eq_ref > ref >fulltext > ref_or_null > index_merge > unique_subquery >index_subquery > range > index > ALL
possible_keys: NULL //这一列显示了查询可以使用哪些索引,是基于查询访问的列和使用的比较操作符来判断的.(可能用到的索引)
如果没有任何索引可以使用,就会显示成null
key: NULL //显示了MySQL决定采用哪个索引来优化对该表的访问 (真正用到的索引)
key_len: NULL //显示mysql决定使用的键长度,如果键是null,则长度为null。
ref: NULL //显示了之前的表在key列记录的索引中查询值所用到的列或常量
rows: 11 //显示的是MySQL为了找到所需的值而要读取的行数.
filtered: 10.00 //进行全文索引检索。
Extra: Using where
2.查看mysql的慢查询日志.
1)查看慢查询日志是否开启
show variables like "%quer%";
slow_query_log | ON //ON开启慢查询
slow_query_log_file | mysql-slow.log //保存所在日志
long_query_time | 10.000000 //慢查询秒数
2)查看慢查询的次数
show status like "%quer%";
Slow_queries | 0 //慢查询次数
3.修改慢查询的时间(my.ini)
long_query_time=6 //定位为6秒,记录为慢查询sql
4.重启mysql服务器
net stop mysql57
net start mysql57
优化表空间
optimize table sales;也就是把
1.myisam表没有问题.
2.innodb表ibdata1文件无法回收以删除数据表空间.
索引优化
索引实例
索引用于快速找出在某个列中有一特定值的行。对相关列使用索引是提高SELECT操作性能的最佳途径。
- 对与创建的多列索引,只要查询的条件中用到最左边的列,索引一般就会被使用。如下创建一个复合索引。
mysql>create index ind_sales2_com_mon on sales2(company_id,moneys);
然后按company_id进行查询,发现使用到了复合索引
mysql>explain select * from sales2 where company_id=2006\G;
使用下面的查询就没有使用到复合索引。
mysql>explain select * from sales2 where monye=1\G;
check表检查结构是否报错:
一般情况用的不多
mysql> check table v_user;
+-----------+-------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+-----------+-------+----------+----------+
| user.user | check | status | OK |
+-----------+-------+----------+----------+
索引的存储分类:
1.myisam
1)frm 表结构
2)myd 表数据
3)myi 表索引
2.innodb
1)frm 表结构
2)ibd 索引+部分表数据
3)ibdata1 所有表共享空间
复合索引:
对于创建的多列索引,只要查询的条件中用到最左边的列,索引一般就会被使用.
1、 Mysql联合索引最左匹配原则
参考文档:
https://segmentfault.com/a/1190000015416513
like关键字:
当使用like进行搜索时,%在前索引可能会失效.
desc select * from user where username like 'linux%'\G
null判断:
当判断null值时会使用username这一列的索引.
desc select * from user where username is null;
or关键字:
在使用or的情况下两边的索引都有可能失效.
desc select * from user where username='user7' or age=15\G
字段和值类型不同:
当条件中字段和值的类型不同时,该字段的索引可能会失效.
desc select * from user where username=200\G
查看索引的使用频次:
mysql> show status like "%Handler_read%";
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_key | 42 | #越大越好
| Handler_read_rnd_next | 306 | #越小越好
+-----------------------+-------+
多表查询索引使用:
目前5.7的版本中常用的多表查询都进行索引优化.
desc select * from t1 where class_id in(select id from class)\G
desc select t1.* from t1,class where t1.class_id=class.id\G
desc select t1.* from class left join t1 on t1.class_id=class.id\G