• mysql 优化(3)


    using filesort 不能利用索引来进行分组或排序,利用filesort算法在内存或者磁盘进行排序
    using temporary 先在内存中进行分组,归并等操作,不够利用磁盘

    SELECT id FROM table ORDER BY RAND() LIMIT n;
    优化成=&get;
    SELECT id FROM table t1 JOIN (SELECT RAND() * (SELECT MAX(id) FROM table) AS nid) t2 ON t1.id &get; t2.nid LIMIT n;

    两个表left join,一般不会被改写顺序,
    而三个以上的left join他们之间也会自动选择顺序了
    SQL优化要点
    1、 消除type = ALL
    2、 消除 using filesort
    3、 消除 using temporary
    4、 多表连接时,注意连接顺序是否我们提交的顺序,是否被改写了(有时候,被改写了反而更好,不一而论)
    5、 注意 key_len 是否达到了预期,整个联合索引尽可能都被利用
    其他优化建议
    • 使用长连接避免连接开销。或者加大thread_cache_size,或者使用thread pool;
    • 重要业务上线前,关键SQL必须逐个EXPLAIN分析,确保都有适当的索引;
    • 请求频率很高的表上禁止运行长读写事务,避免发生严重锁等待等性能问题;
    • 类似长URL(低于255长度)列检索,建议先进行HASH后创建索引,其检索效率会高很多倍;
    • 区分冷热表,让热数据尽可能放在buffer中,提高读写效率;
    • 如果需要经常统计结果,建议新增计数器,或者使用redis、mc来代替MySQL;
    • 非精确性统计表总记录数时,可以执行SHOW TABLE STATUS查看估算结果;
    • 所有列类型都设置默认值,严禁允许默认为NULL值的;
    • 如果不能把多个大字段(长VARCHAR、TEXT、BLOB类型)分离到子表的话,就想办法合并成一个大字段,避免频繁的off-page;
    • 个别时候可能需要采用冗余字段来存储,比如部分长度(尤其是取最右边的长度),或者反向存储,方便特殊的检索需求;
    • 频繁读取的热数据,尽可能缓存在redis、mc中,哪怕只缓存10秒,如果每秒请求1000次的话,也可以减少1万次请求;
    • 可以的话,采用多行记录同时INSERT,或者LOAD方式批量写入,提高写入效率,但也要避免锁时间太久的问题;

    Index Condition Pushdown(ICP)
    • 5.6以上,优化索引查询效率
    • 以前:先检索全部记录,而后进行一次过滤
    • 现在:边检索记录,边进行过滤
    • 好处:降低SQL层得到的结果集,提高处理效率
    • 优化支持range、ref、eq_ref、eq_or_null类型查询
    • 查询优化器提示:Using index condition

    • 在不支持ICP之前,MySQL进行索引查询时,会先根据索引查询记录,再根据WHERE条件来进行过滤。
    • 在支持ICP后,MySQL在根据索引查找的同时,会根据WHERE条件对结果进行过滤,将WHERE条件的过滤操作放在存储引擎层,这样一来,
    在一些查询中,ICP会大大提高上层SQL层(SERVER层)读取记录(fetch)效率,从而提高整体tps。

    show global variables like 'optimizer_switch';
    启用ICP:
    set global optimizer_switch = "index_condition_pushdown=on";
    关闭ICP:
    set global optimizer_switch = "index_condition_pushdown=off";

    新特性:MRR & BKA
    MRR(Multi-Range Read)
    • 5.6以上,减少磁盘随机访问,将随机访问转变成顺序访问,提高IO性能
    • 适用于range、ref、eq_ref类型查询
    • 数据访问较为顺序,查询辅助索引时,对查询结果先按照主键(ROWID)进行排序,并按照主键排序后的顺序,进行顺序查找
    • 减少buffer pool中的页面被替换次数
    • 批量处理对索引的查询操作
    MRR工作方式:
    • 将查询到的辅助索引键值放在一个缓冲中,这时缓冲中的数据是根据辅助所以进行排序的
    • 将缓冲中的键值根据 ROWID进行排序
    • 根据ROWID的排序顺序来访问实际的数据文件

    新特性 BKA(Batched Key Access)
    在MySQL 5.6中,BKA(Batched Key Access)联接算法可同时用于表连接以及join buffer时的索引访问。
    BKA算法支持inner join、outer jon、semi-join,以及nested-outer join。BKA算法使得表扫描效率更高,以此实现JOIN优化。
    此前BNL(Block Nested-Loop)联接算法只能用于inner join优化,现在也支持outer join、semi join、以及nested outer join等。

    InnoDB引擎优化 - innodb buffer pool转储、预热
    转储文件名为ib_buffer_pool, 转储的文件中只记录了space id和page no,所以非常小
    InnoDB引擎优化 - read only transaction,只读事务
    默认开启事务是READ WRITE,可以在开启事务时指定: START TRANSACTION READ ONLY;
    如果以autocommit运行select,则视其为READ ONLY
    只读事务不会为其创建事务,提高只读效率,只读事务减少了创建read view的开销,因为这是个全局锁竞争的热点。
    InnoDB引擎优化 - 物化Innodb表的统计信息
    控制选项:innodb_stats_persistent
    当开启该选项后,就会将表的统计信息记录到ibdata中,只有手动执行ANALYZE TABLE才会对其进行更新。
    在5.6中,引入的一个新参数innodb_stats_auto_recalc用于控制是否进行自动统计信息计算。当表上的记录修改超过1/16比例,或者总共超过20亿行时,
    或者访问information_schema下的一些特定表,就会对统计信息重新计算;这只对在建表时打开了innodb_stats_persistent或者指定了建表选项STATS_PERSISTEND=1生效,
    采样page的个数通过参数innodb_stats_persistent_sample_pages来控制(实际读取的page数会大于该值)。

    information_schema.TABLES
    information_schema.STATISTICS
    information_schema.PARTITIONS
    information_schema.KEY_COLUMN_USAGE
    information_schema.TABLE_CONSTRAINTS
    information_schema.REFERENTIAL_CONSTRAINTS

    InnoDB引擎优化 - 引入独立page cleaner thread和purge thrad
    启用独立的page cleaner线程和 purge thread,通过选项 innodb_puge_threads 来控制。在5.6版本下,还只能设置为1,从5.7开始,就可以设置成更大值
    InnoDB引擎优化 - 死锁检测增强
    启用 innodb_print_all_deadlocks 选项,即可将全部死锁信息打印输出到日志文件中,在以前,只能在show engine innnodb status中打印最后一次死锁信息
    InnoDB引擎优化 - 独立undo表空间
    innodb_undo_tablespaces #undo 表空间的个数,将所有的回滚段平分到这么多个ibd表空间文件中,这个值一旦设置,则不可更改。
    配置这个及下面的选项,是为&get;了将undolog从Ibdata中独立出来,并且由于undo log是随机写,可以放到SSD盘上来提高性能
    innodb_undo_directory #表示undo log表空间文件的路径,启动前设置
    innodb_undo_logs #等同于老版本的innodb_rollback_segments,一个事务中最多可以多少个回滚段。
    InnoDB引擎优化 - InnoDB page size增强
    支持4K、8K格式,适用于绝大多数行平均大小较低值的场景。
    从5.7开始,则新增支持32K、64K格式,以适应数据仓库中长日志格式场景。

    InnoDB引擎优化 - page checksum增强
    innodb_checksum = 0|1,是否校验innodb磁盘文件
    innodb_checksum_algorithm #更快的checksum算法(crc32), innodb|crc32|none|strict_innodb|strict_crc32|strict_none
    binlog_checksum = CRC32 | NONE,校验算法
    master_verify_checksum = 0|1,读取binlog时,是否校验
    slave_sql_verify_checksum = 0|1,在slave上读取relay log时,是否校验relay log

    5.6新特性:EXPLAIN增强
    支持DML的EXPLAIN,但是需要注意可能有不准确的情况。
    EXPLAIN结果中,type列有时候会变成range,但实际上是use index的,和改成SELECT后的执行计划不一致。
    而如果是多表的DML执行计划解析,则没有问题。

    5.6新特性:查询优化器跟踪
    启用了optimizer_trace功能,和oracle的执行计划类似,可以输出json格式结果,并且开始往CBO方向靠。
    http://imysql.com/2014/08/05/a-fake-bug-with-eq-range-index-dive-limit.shtml
    http://blog.163.com/li_hx/blog/static/18399141320147521735442/

    show tables like ‘INNODB_SYS_%';

    5.6新特性:复制增强
    1、 开始支持GTID,极大方便了复制的便利性以及可靠性;
    2、 支持多线程并发复制,不过只能是基于database级别的,意义不大,可以用percona或者mariadb分支特性;
    3、 slave库延迟更新,防止误操作;
    4、 binlog_row_image = full|minimal|noblob,减少binlog大小;同时binlog和relay log也支持crash safe了,上面checksum已介绍过;
    5、 支持将master、slave、relay log info等信息记录在innodb表中,取代原先的写文件做法,提高可靠性;
    6、 可以利用mysqlbinlog构建一个binlog server:--read-from-remote-server --raw
    7、 binlog group commit
    Tips:当引入binlog group commit后,sync_binlog的含义就变了,假定设为1000,表示的不是1000个事务后做一次fsync,而是1000个事务组。

    5.7新特性:其他
    innodb_purge_threads 可以设置大于1,有效的进行purge
    InnoDB REDO log size up to 512 Gbyte (日志大小达到了512G,有效的提高了检查点的写入)

    mysql选择,percona,mariadb
    Percona分支特有选项/参数
    enforce_storage_engine
    expand_fast_index_creation
    ² 扩展快速创建索引特性,尽可能避免在一些场景下执行唯一约束、外键约束检查,提高性能
    ² mysqldump中新增选项 --innodb-optimize-keys,在备份文件最莫问再加上enable keys,以及唯一约束、外键约束检查等
    extra_max_connections
    extra_port
    ² thread pool功能的扩展,允许使用额外端口和线程作为管理员救命用
    innodb_kill_idle_transaction
    ² 0(不启用)/N秒,干掉超过N秒的事务(不光是只读查询)
    innodb_log_block_size
    ² 默认512字节,可以调整成4K,以适应SSD设备,提高IO性能
    innodb_show_locks_held
    ² 在SHOW INNODB STATUS中显式多少个锁信息
    innodb_show_verbose_locks
    ² 0/1,是否在SHOW INNODB STATUS中显式更多锁相关的信息
    log_slow_filter
    ² slowlog过滤器,哪些类型的slowlog不记录
    log_slow_rate_limit
    ² 1 ~ 1000,和log_slow_rate_type结合起来用。记录每 1/N次slowlog,不全记录
    log_slow_rate_type
    ² slowlog控制范围是每个session,还是每个query。如果是每个session,需要注意连接池情况下无法生效,并且对复制线程也不生效
    log_slow_sp_statements
    ² 是否记录存储过程产生的slowlog
    log_slow_verbosity
    ² 设置slowlog中,哪些类型的信息要被记录下来,一般设置为full
    max_binlog_files
    ² 至多保留多少个binlog文件
    slow_query_log_timestamp_always
    ² 每次slowlog中,是否总是记录时间戳
    thread_statistics
    userstat
    ² 和thread_statistics一起,设置是否统计每个user和thread的信息,存储在information_schema的几个表中

    CLIENT_STATISTICS
    INDEX_STATISTICS
    TABLE_STATISTICS
    THREAD_STATISTICS
    USER_STATISTICS
    slow_query_log_timestamp_precision
    slow_query_log_use_global_control
    Innodb_deadlocks
    Innodb_max_trx_id
    Innodb_purge_trx_id
    Innodb_s_lock_os_waits
    Innodb_s_lock_spin_rounds
    Innodb_s_lock_spin_waits
    Innodb_x_lock_os_waits
    Innodb_x_lock_spin_rounds
    Innodb_x_lock_spin_waits

    【重要】如果需要TokuDB,那么建议它和MariaDB组合使用

  • 相关阅读:
    竞赛入门经典 3.2竖式问题
    竞赛入门经典 3-4竖式
    hdu 3547 (polya定理 + 小高精)
    浅入 dancing links x(舞蹈链算法)
    计算阶乘的另一些有趣的算法(转载)
    莫比乌斯反演
    STL的常用用法、函数汇总(不定时更新)
    博弈论的总结
    14年安徽省赛数论题etc.
    CCF 第六次计算机职业认证 第四题 收货 stl动态存储和fleury算法的综合应用
  • 原文地址:https://www.cnblogs.com/yhq1314/p/10678617.html
Copyright © 2020-2023  润新知