美文网首页
MySQL常用优化方案

MySQL常用优化方案

作者: 后厂村村长 | 来源:发表于2021-09-12 18:33 被阅读0次

    尽量减少锁冲突和死锁

    尽量使用较低的隔离级别
    精心设计索引,并尽量使用索引访问数据,使加锁更精确,从而减少锁冲突的机会。
    选择合理的事务大小,小事务发生锁冲突的几率也更小。
    给记录集显示加锁时,最好一次性请求足够级别的锁。比如要修改数据的话,最好直接申请排他锁,而不是先申请共享锁,修改时再请求排他锁,这样容易产生死锁。
    不同的程序访问一组表时,应尽量约定以相同的顺序访问各表,对一个表而言,尽可能以固定的顺序存取表中的行。这样可以大减少死锁的机会。
    尽量用相等条件访问数据,这样可以避免间隙锁对并发插入的影响。
    不要申请超过实际需要的锁级别;除非必须,查询时不要显示加锁。
    对于一些特定的事务,可以使用表锁来提高处理速度或减少死锁的可能。

    常见方式

    1.查看慢查询日志(需要设置开启)
    2.通过pt-query-digest工具分析(第三方工具)
    3.设置set profiling = 1;开启服务,执行show profiles,查看所有语句会监测消耗时间存到临时表。
    4.找到消耗时间大的ID,执行show profile for query 临时表ID;查到原因后,执行 set profiling = 0 关闭;
    5.使用show status,show processlist 等命令查看;
    6.使用explain分析单条SQL语句。

    show profiles;

    语句执行后,会显示三个字段:Query_ID(执行ID) | Duration(持续时间)| Query(查询语句)
    拿到后Query_ID后,可执行show profile for query Query_ID,查看详细的准备时间,执行时间、执行结束(preparing、executing、end)等。

    show processlist;

    显示用户正在运行的线程,需要注意的是,除了 root 用户能看到所有正在运行的线程外,其他用户都只能看到自己正在运行的线程,看不到其它用户正在运行的线程。除非单独个这个用户赋予了PROCESS 权限。
    显示字段包含:User| Host| db | Command | Time| State| Info等。

    explain

    解析语句,查询是否命中索引,及,命中何种索引,用以判断是否符合我们的预期。
    返回字段包含:select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra 等。

    select_type 常见类型:
    (1) SIMPLE(简单SELECT,不使用UNION或子查询等)
    (2) PRIMARY(子查询中最外层查询,查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY)
    (3) UNION(UNION中的第二个或后面的SELECT语句)
    (4) SUBQUERY(子查询中的第一个SELECT,结果不依赖于外部查询)

    table 常见类型:
    显示这一行的数据是关于哪张表的.
    有时不是真实的表名字,看到的是derivedx(x是个数字,我的理解是第几步执行的结果)

    type 常见类型:
    对表访问方式,表示MySQL在表中找到所需行的方式,又称“访问类型”。
    常用的类型有: ALL、index、range、 ref、eq_ref、const、system、NULL(从左到右,性能从差到好)

    ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行
    index: Full Index Scan,index与ALL区别为index类型只遍历索引树
    range:只检索给定范围的行,使用一个索引来选择行;
    ref: 对于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取。如果联接只使用键的最左边的前缀,或如果键不是UNIQUE或PRIMARY KEY(换句话说,如果联接不能基于关键字选择单个行的话),则使用ref。如果使用的键仅仅匹配少量行,该联接类型是不错的。
    eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个来自于前面的表的行组合,从该表中读取一行。这可能是最好的联接类型,除了const类型。它用在一个索引的所有部分被联接使用并且索引是UNIQUE或PRIMARY KEY。
    const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用system
    NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。

    possible_keys
    指出MySQL能使用哪个索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用(该查询可以利用的索引,如果没有任何索引显示 null)
    该列完全独立于EXPLAIN输出所示的表的次序。这意味着在possible_keys中的某些键实际上不能按生成的表次序使用。
    如果该列是NULL,则没有相关的索引。在这种情况下,可以通过检查WHERE子句看是否它引用某些列或适合索引的列来提高你的查询性能。如果是这样,创造一个适当的索引并且再次用EXPLAIN检查查询

    key
    key列显示MySQL实际决定使用的键(索引),必然包含在possible_keys中
    如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

    key_len
    表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度,非实际长度,为最大可能长度。
    注:不损失精确性的情况下,长度越短越好。

    ref
    列与索引的比较,表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值。

    rows
    估算出结果集行数,表示MySQL根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数;

    extra
    该列包含MySQL解决查询的详细信息,有以下几种情况:
    (1).Distinct
    一旦MYSQL找到了与行相联合匹配的行,就不再搜索了
    (2).Not exists
    MYSQL优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行,就不再搜索了
    (3).Range checked for each
    Record(index map:#)
    没有找到理想的索引,因此对于从前面表中来的每一个行组合,MYSQL检查使用哪个索引,并用它来从表中返回行。这是使用索引的最慢的连接之一
    (4).Using filesort
    看到这个的时候,查询就需要优化了。MYSQL需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行;
    (5).Using temporary
    看到这个的时候,查询需要优化了。这里,MYSQL需要创建一个临时表来存储结果,这通常发生在对不同的列集进行ORDER BY上,而不是GROUP BY上;
    (6).Using index
    列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候。
    (7).Using where
    使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。如果不想返回表中的全部行,并且连接类型ALL或index,这就会发生,或者是查询有问题。

    总结:

    • EXPLAIN不会告诉你关于触发器、存储过程的信息或用户自定义函数对查询的影响情况;
    • EXPLAIN不考虑各种Cache;
    • EXPLAIN不能显示MySQL在执行查询时所作的优化工作;
    • 部分统计信息是估算的,并非精确值;
    • EXPALIN只能解释SELECT操作,其他操作要重写为SELECT后查看执行计划;

    相关文章

      网友评论

          本文标题:MySQL常用优化方案

          本文链接:https://www.haomeiwen.com/subject/ckstgltx.html