mysql索引优化

sql优化的几种方式

建表时选取最适用的字段属性,可以将表中字段的宽度设得尽可能小,字段尽量非空

使用JOIN代替子查询

查询过程不产生临时表

索引的字段上尽量不要使用函数进行操作

mysql常见的瓶颈

cpu:CPU饱和一般发生在数据装入内存或从磁盘上读取数据的时候

IO:磁盘I/O瓶颈发生在装入数据远大于内存容量的时候

数据库查询慢该怎么办:

  1. 先执行show status like '%innodb_row_lock%'看看
  2. 然后打开慢查询日志,设定到3秒以上跑一下,在慢查询日志中会记录下 
  3. 在这条sql前加explain查索引是否实现
  4. 在用show profile 查看资源消耗情况,是否有临时表产生

Explain进行执行计划分析

Mysql中有专门负责优化SELECT语句的优化器模块,使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的,分析你的查询语句或是表结构的性能瓶颈,具体包含:表的读取速度,数据读取操作的操作类型,哪些索引可以被使用,哪些索引被实际使用,表之间的引用,每张表有多少行被优化器查询

  • id:在一个大的查询语句中每个select关键字都对应一个唯一的id,id越大优先级越高
  • select_type:select 关键字对应的查询是类型,普通查询,联合查询,子查询等
  • table:显示这一句sql是关于哪种表
  • type:显示查询使用了何种类型  system>const>eq_ref>ref>range>index>all  一般要求至少达到range
  • possible_keys:可以应用到这种表中的索引,一个或多个
  • key:实际使用的索引,如果为null则没有用到索引
  • key_len:表示索引中使用的字节数,不影响精度的情况下,越小越好(节省空间,减少磁盘IO)
  • ref:索引是怎么用的,const表示赋予clo2常量, shared.t2.col1 :库名.表名.列名  表示col1被当做主外键的连接条件
  • rows:大致估算出吵到所需记录 要读取的行数,越小越好
  • extra:其他额外的信息,

       Using filesort : 无法使用到索引完成排序操作,不行 ,

       Using temporary : 使用了临时表,不行 

       Using index : 表示相应的select操j作使用了覆盖索引,避免了访问表的数据行,效率不错

备注:system>const>eq_ref>ref>range>index>all 

system:系统表,少量数据,往往不需要进行磁盘IO
const:使用常数索引,MySQL只会在查询时使用常数值进行匹配。
eq ref:唯一索引扫描,只会扫描索引树中的一个匹配行
ref:非唯一索引扫描,只会扫描索引树中的一部分来查找匹配的行。
range:范围扫描,只会扫描索引树中的一个范围来查找匹配的行。
index:全索引扫描,会遍历索引树来查找匹配的行
ALL:全表扫描,将遍历全表来找到匹配的行。

索引失效

  • 遵循最佳左前缀法则,不在索引列上做任何操作(计算,函数,自动或者手动类型转换)否则索引会失效转向全表扫描
  • 存储引擎不能使用索引中范围条件右边的列,between and 会导致索引失效
  • is null , is not null , like 以通配符开头('%abc...')索引会失效,只有'abc%'这种不会失效
  • 如果非要使用'%abc%'且不想让索引失效,可以通过覆盖索引的方式来解决
  • or语句会导致索引失效,可以用in语句来代替(in最多200个值否则会出问题)
  • 大于小于号会导致索引失效
// 都可以用到索引,mysql会自动优化,但是不推荐
explain select * from test03 where c1='a1' and c2='a2' and c4='a4' and c3='a3';
explain select * from test03 where c1='a1' and c2='a2' and c4>'a4' and c3='a3';
  • order by 导致索引失效的情况:
// 只有c1 和 c2 用到了索引,c3作用在排序而不是查找 
explain select * from test03 where c1='a1' and c2='a2' and c4='a4' order by c3;

// 都只是c1和c2索引起作用,但是下面这条出现了filesort
 explain select * from test03 where c1='a1' and c2='a2' order by c3;
 explain select * from test03 where c1='a1' and c2='a2' order by c4;

// 只用c1一个字段索引,但是c2、c3用于排序,无filesort
explain select * from test03 where c1='a1' and c5='a5' order by c2,c3;

// 出现了filesort,我们建的索引是1234,它没有按照顺序来,3 2 颠倒了
explain select * from test03 where c1='a1' and c5='a5' order by c3,c2;
 
// 本条是可以的,本例有常量c2的情况,和上面一条比较
explain select * from test03 where c1='a1' and c2='a2' and c5='a5' order by c3,c2;

order by 使用索引排序

永远是小表驱动大表

mysql支持两种排序方式:fileSort和Index,Index效率高

order by 子句,尽量使用index方式排序,避免使用FileSort方式排序

order by语句使用索引最左前列,使用where子句与order by子句条件组合满足索引最左前列

为什么不适用select *

  • mysql拿到一条命令,会去解析命令、优化查询,然后去存储引擎执行查找.SELECT * 语句取出表中的所有字段,会解析更多的 对象,字段,权限,属性相关,这会对服务器资源造成浪费,导致优化和效率问题,对服务器的性能产生一定的影响,例如:采用order by 排序造成不必要的字段也进行了排序,影响效率
  • 使用SELECT * 语句将不会使用到覆盖索引,不利于查询的性能优化.(索引覆盖:索引覆盖是一种速度极快,效率极高,业界推荐的一种查询方式.就是select的数据列只用从索引中就能够获得,不必从数据表中读取,也就是查询列要被所使用的索引覆盖)
  • SELECT * 语句没有说明将要取出哪些字段进行操作,不具备针对性,不推荐,不利于后期代码维护

group by 关键字优化同order by 

where 高于having, 能写在where限定的条件不要写在having里面

慢查询日志 slow_query_log

用来记录mysql中响应时间超过阀值long_query_time的语句,mysql默认阀值是10秒,可以通过set global long_query_time = 3去修改时间,执行时间大于阈值的sql将会被记录下来

如果不是调优需要的话,一般不建议启动该参数,多少w都会影响性能

查看是否开启及如何开启:show variables like '%slow_query_log%';

开启: set global slow_query_log = 1 只对当前数据库生效 ,mysql重启后会失效,永久生效,就必须修改配置文件my.ini (其它系统变量也是)

查看有多少条慢sql:show global status like '%Slow_queries%';

日志分析工具mysqldumpslow    

具体可以使用 mysqldumpslow --help 查询命令帮助 

      s :表示按何种方式排列, r 返回记录 , t 查询时间 

      得到返回记录集最多的10个SQL     

     mysqldumpslow -s r -t 10 /var/lib/mysql/atguigu-slow.log

     得到访问次数最多的10个SQL

     mysqldumpslow -s c -t 10 /var/lib/mysql/atguigu-slow.log

     得到按照时间排序的前10条里面含有左连接的查询语句

     mysqldumpslow -s t -t 10 -g "left join" /var/lib/mysql/atguigu-slow.log

     另外建议在使用这些命令时结合 | 和more 使用 ,否则有可能出现爆屏情况

     mysqldumpslow -s r -t 10 /var/lib/mysql/atguigu-slow.log | more

show profile

show profile 是mysql提供可以用来分析当前会话中语句执行的资源消耗情况的,默认情况下,参数处于关闭状态,并保存最近15次的运行结果

查看是否开启命令:Show variables like 'profiling';   开启 set profiling = on;

命令show profiles 可以查看哪天sql影响性能

进一步查看这条sql从开始到结束资源消耗情况

show profile cpu,block io for query 8;  //可以查cpu,内存,io等所有信息,可以查看执行过程中是否产生了临时表

临时表慢的原因: 要拷贝数据导临时表,用完再删除

Creating tmp table 创建临时表,Copying to tmp table on disk 把内存中临时表赋值到磁盘上,危险


    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值