MySQL高级(索引优化+慢查询定位)

1、先谈谈事务

1. ACID特性

1.1 原子性: 事务是最小的执行单位,不容许分割。事务的原子性确保动做要么所有完成,要么彻底不起做用;
1.2 一致性: 执行事务先后,数据库从一个一致性状态转换到另外一个一致性状态。
1.3 隔离性: 并发访问数据库时,一个用户的事物不被其余事务所干扰,各并发事务之间数据库是独立的;
1.4 持久性: 一个事务被提交以后。它对数据库中数据的改变是持久的,即便数据库 发生故障也不该该对其有任何影响。mysql

2. 事务隔离级别

2.1 READ_UNCOMMITTED(未提交读): 最低的隔离级别,容许读取还没有提交的数据变动,可能会致使脏读、幻读或不可重复读
2.2 READ_COMMITTED(提交读): 容许读取并发事务已经提交的数据,能够阻止脏读,可是幻读或不可重复读仍有可能发生
2.3 REPEATABLE_READ(可重复读): 对同一字段的屡次读取结果都是一致的,除非数据是被自己事务本身所修改,能够阻止脏读和不可重复读,但幻读仍有可能发生。
2.4 SERIALIZABLE(串行): 最高的隔离级别,彻底服从ACID的隔离级别。全部的事务依次逐个执行,这样事务之间就彻底不可能产生干扰,也就是说,该级别能够防止脏读、不可重复读以及幻读。可是这将严重影响程序的性能。一般状况下也不会用到该级别。sql

Mysql 默认采用的 REPEATABLE_READ隔离级别

2、了解索引

1. 什么是索引

索引是一种帮助MySQL高效获取数据的数据结构

2. 优点和劣势

优点:数据库

  1. 提升数据检索的效率,下降数据库的IO成本
  2. 下降数据排序的成本,下降了CPU的消耗

劣势:数据结构

  1. 索引列要占用空间
  2. 下降了更新表的速度(INSERT、UPDATE)
  3. 创建优秀索引的时间成本

3. 哪些状况须要建立索引

  • 主键自动创建惟一索引
  • 频繁做为查询条件的字段应该建立索引
  • 查询中与其余表关联的字段,外键关系创建索引
  • where条件里用不到的字段不建立索引
  • 单键/组合索引的选择问题,在高并发倾向建立组合索引
  • 查询中排序的字段,排序字段若经过索引去访问将大大提升排序速度
  • 查询中统计或分组字段

4. 哪些状况下不须要建立索引

  • 表记录太少
  • 频繁更新的字段不适合建立索引,由于每次更新不仅仅是更新了记录还会更新索引,加剧了IO负担
  • 数据重复且分布平均的表字段(若某个数据列包含许多重复的内容,为它创建索引就没有太大的实际效果,即过滤性很差的字段)

3、EXPLAIN【重点】

使用EXPLAIN关键字能够模拟优化器执行SQL查询语句, 从而知道MYSQL是如何处理你的SQL语句的,分析你的查询语句或是表结构的性能瓶颈

EXPLAIN查询出来的字段

a、id并发

①id相同,执行顺序由上至下函数

②id不一样,id值越大优先级越高,越先被执行高并发

b、select_type性能

查询的类型,主要是用于区别普通查询、联合查询、子查询等的复杂查询

c、table优化

显示这行的数据是关于哪张表的。

d、type(最好到最差的顺序)spa

  • system:表只有一行记录(等于系统表),这是const的特例,平时不会出现,这个能够忽略
  • const:表示经过索引一次就找到了,const用于比较primary key或者unique索引。由于只匹配一行数据,因此很快。如将主键置于where列表中,MySQL就能将该查询转换为一个常量
  • eq_ref:惟一性索引扫描,对于每一个索引键,表中只有一条记录与之匹配。经常使用于主键或惟一索引扫描
  • ref:非惟一性索引扫描,返回匹配某个单独值的全部行,可能会找到多个符合符合条件的行
  • range:只检索给定范围的行,使用一个索引来选择行。key列显示使用了哪一个索引。通常是你的where语句中出现between、<、>、in等的查询,这种范围扫描索引扫描比全表扫描要好
  • index:index与all的区别为index类型只遍历索引树,也就是说,虽然all和index都是读全表,但index是从索引中读取的,而all是从硬盘中读取的
  • all:遍历全表
备注:通常来讲,得保证查询至少达到range级别,最好能达到ref

e、possible_keys

可能应用到这张表的索引

f、key

实际使用的索引

g、key_len

索引使用的字节数,在不损失精确性的状况下,长度越短越好

h、ref

显示索引的哪一列被使用了

i、rows

大体估算出找到所需记录所须要读取的行数

j、Extra

  • Using filesort:说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。MySQL中没法利用索引完成的排序操做称为“文件排序”
  • Using temporary:使用了临时表保存中间结果,MySQL在对查询结果排序时使用临时表,常见于排序order by和分组查询group by
  • USING index:表示相应的select操做中使用了覆盖索引,避免访问了表的数据行

什么状况下索引会失效

  • 全值匹配
  • 最佳左前缀法则
  • 不在索引列上作任何操做(计算、函数、(手动或自动)类型转换),会致使索引失效而转向全表扫描
  • 存储引擎不能使用索引中范围条件右边的列
  • 尽可能使用覆盖索引
  • MySQL在使用不等于(!=或<>)的时候没法使用索引会致使全表扫描
  • is null,is not null也没法使用索引
  • like以通配符开头(“%abc..‘)MySQL索引失效会变成全表扫描的操做
  • 字符串不加单引号索引失效(自动类型转换)
  • or左边有索引、右边没索引也会失效

order by关键字优化

  • 尽可能使用index方式排序,避免使用filesort方式。
  • order by知足两种状况会使用index排序:①、order by语句使用索引最左前列,②、使用where子句与order by子句条件列组合知足索引最左前列
  • 双路排序:MySQL4.1以前,两次扫描磁盘
  • 单路排序:从磁盘读取查询须要的全部列,按照order by列在buffer对它们进行排序,而后扫描排序后的列进行输出,效率更高一点,可是它会使用更多的空间,由于它把每一行都保存在内存中了
优化策略: 增大sort_buffer_size参数的设置、增大max_length_for_sort_data参数的设置

group by关键字优化

实质是先排序后进行分组,遵守索引键的最佳左前缀,当没法使用索引列时,增大sort_buffer_size+max_length_for_sort_data参数的设置

3、慢查询【重点】

1. 慢查询日志是什么

MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。

具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。long_query_time的默认值为10,意思是运行10秒以上的语句。

由他来查看哪些SQL超出了咱们的最大忍耐时间值,好比一条sql执行超过5秒钟,咱们就算慢SQL,但愿能收集超过5秒的sql,结合以前explain进行全面分析。

2. 怎么用

默认状况下,MySQL数据库没有开启慢查询日志,须要咱们手动来设置这个参数。(固然,若是不是调优须要的话,通常不建议启动该参数,由于开启慢查询日志会或多或少带来必定的性能影响。慢查询日志支持将日志记录写入文件。)
-- 查看开启状况
SHOW VARIABLES LIKE '%slow_query_log%';

-- 开启(只对当前数据库生效,若是要永久生效,就必须修改配置文件my.cnf)
set global slow_query_log=1;

3. Show Profile【重点】

3.1. 是什么
mysql提供能够用来分析当前会话中语句执行的资源消耗状况。能够用于SQL的调优的测量,相比explain,show profile展现的数据更加详尽。
3.2. 怎么用
-- 查看是否开启
show variables like 'profiling';

-- 开启功能,默认是关闭,使用前须要开启
set profiling=1;

-- 查看结果
show profiles;

-- 诊断SQL
show profile cpu,block io for query n;
-- 还能够经过SELECT * FROM information_schema.profiling WHERE query_id = n ORDER BY seq;获取

clipboard.png

相关文章
相关标签/搜索