mysql5.7性能提升一百倍调优宝典( 三 )

  • Repeatable-read: 这是MySQL的InnoDB引擎默认的隔离级别,它阻止查询的任何行被其他事务更改 。因此,阻塞不可重复读,而不是幻读 。也就是说在可重复读中,可能会出现幻读 。重复读使用一种中等严格的锁定策略,以便事务中的所有查询都能看到来自相同快照(即事务启动时的数据)的数据 。当拥有该级别的事务执行 UPDATE ... WHERE, DELETE ... WHERE, SELECT ... FOR UPDATE和LOCK IN SHARE MODE操作时,其他事务可能需要等待 。
  • Read-Committed-推荐: 事务无法看到来自其他事务的未提交数据,但可以看到当前事务启动后另一个事务提交的数据 。当拥有这种级别的事务执行 UPDATE ... WHERE or DELETE ... WHERE操作时,其他事务可能需要等待 。但是该事务可以执行 SELECT ... FOR UPDATE, and LOCK IN SHARE MODE操作,其他事务不需要等待 。
  • 串行化(SERIALIZABLE)-极力不推荐,串行化隔离级别是最高的隔离级别,它使用了最保守的锁策略 。它阻止任何其他事务插入或更改此事务读取的数据,直到该事务完成 。简单的来说,就是一个事务一个事务的来执行,显然性能会很低 。在这种隔离级别下,一个事务中的相同查询可以反复执行,每次查询结果是一样的 。从当前事务开始执行,任何更改另一个事务提交的数据的尝试都会导致当前事务等待(阻塞) 。这是SQL标准指定的默认隔离级别(注意不是MySQL) 。在实践中,这种严格程度是很少需要的 。
  • 读未提交(READ-UNCOMMITTED)-它是最低的隔离级别,虽然性能最高,但也不推荐
  • 它会读取到其他事务修改尚未提交的数据,使用此隔离级别就需要非常小心,认识到这种级别下的查询结果可能不一致或不可复制,这取决于其他事务同时在做什么 。通常,具有此隔离级别的事务只执行查询,而不执行插入、更新或删除操作 。
  • 在实际环境中,应当根据是否允许出现脏读(dirty reads),不可重复读(non-repeatable reads)和幻读(phantom reads )现象而选择相应的隔离级别 。例如在大数据中,少量的数据不一致不会影响到最后的决策,这种情况下可以使用较低的隔离级别以提交性能和并发性 。
  • 如果不配的后果:
    默认就是repeatable-read
    配置实例:
    transaction_isolation = READ-COMMITTED
    11)explicit_defaults_for_timestamp
    推荐设置:
    1
    作用:
    1. mysql5.7默认对于timestamp字段会显示“系统当前日期”,就算你在插表时这个timestamp字段留空,它在select出来时也会显示系统日期 。因此,这个值的影响范围是你在建表时导致的 。
    2. 系统默认这个值是0,在0的情况下,你要让该表的timestamp字段在为null时不显示系统默认时间,你的建表必须为:create table order(o_id int ,updateed_time timestamp null default null) ;
    3. explicit_defaults_for_timestamp 变量会直接影响表结构,也就是说explicit_defaults_for_timestamp的作用时间是在表定义的时候;你的update | insert 想通过它去改变行为已经太晚了!
    4. 因此,我推荐把这个值设为1.
    如果不配的后果:
    默认为0
    配置实例:
    explicit_defaults_for_timestamp = 1
    12)join_buffer_size
    推荐设置:
    16M
    作用:
    1. 系统默认大小为:512k,mac下默认大小为:256k,针对128GB,1万并发的mysql我推荐给到的值为:8~16M
    2. 对于JOIN KEY 有索引和二级索引,JOIN KEY 无索引mysql会使用到join_buffer_size,一般建议设置一个很小的 GLOBAL 值,完了在 SESSION 或者 QUERY 的基础上来做一个合适的调整 。如果你拍脑袋给也个4g,我们有1000个并发,就是用掉了4T的内存 。。。4T啊 。。。你以为你是小型机 。适当的去改变它确实可以带来一定的提速,但并不是说很多值越大越好,为什么我们设置成4m呢?我们假设我们的mysql所在的vm是128gb,一根这样的join(如果被用到)是4M,1万个也不过用掉40G,而根据官方说法,total加在一起产生的join_buffer_size不要超过你所在系统的50%.默认512k肯定是小了点,我们可以适当放宽,比如说:2M,在实际使用场景时我们发觉有这样的高频操作(要看高频出现的有意义的sql的执行计划,并确认该计划的:执行cost如: "query_cost": "1003179606.87",它产生的cost为:0.93个G,如果它真的很高频出现在调优sql到无法调优的程度,我们会去做set session join_buffer_size = 1024 * 1024 * 1024;这样的操作 。而不是在一开始的my.cnf中去分配一个暴大的值,我们这边基于128gb,1万connection的并发来说,你给个16M不算小也不算多,我推荐给到8~16M间(这是指在一开始) 。


      推荐阅读