MySQL数据库性能优化

MySQL架构

mysql架构图

查询缓存

查询缓存(Query Cache)原理:

缓存SELECT操作或预处理查询的结果集和SQL语句,当有新的SELECT语句或预处理查询语句请求,先去查询缓存,判断是否存在可用的记录集,判断标准:与缓存的SQL语句,是否完全一样,区分大小写

优缺点:

不需要对SQL语句做任何解析和执行,当然语法解析必须通过在先,直接从Query Cache中获得查询结果,提高查询性能
查询缓存的判断规则,不够智能,也即提高了查询缓存的使用门栏,降低其效率查询缓存的使用,会增加检查和清理Query Cache中记录集的开销

哪些查询可能不会被缓存

  • 查询语句中加了SQL_NO_CACHE参数
  • 查询语句中含有获得值的函数,包含自定义函数,如:NOW()CURDATE()GET_LOCK()RAND()CONVERT_TZ()
  • 对系统数据库的查询:mysqlinformation_schema查询语句中使用SESSION级别变量或存储过程中的局部变量
  • 查询语句中使用了LOCK IN SHARE MODEFOR UPDATE的语句,查询语句中类似SELECT ... INTO导出数据的语句
  • 对临时表的查询操作;存在警告信息的查询语句;不涉及任何表或视图的查询语句;某用户只有列级别权限的查询语句
  • 事务隔离级别为Serializable时,所有查询语句都不能缓存

查询缓存相关的服务器变量

  • query_cache_min_res_unit:查询缓存中内存块的最小分配单位,默认4k,较小值会减少浪费,但会导致更频繁的内存分配操作,较大值会带来浪费,会导致碎片过多,内存不足
  • query_cache_limit:单个查询结果能缓存的最大值,默认为1M,对于查询结果过大而无法缓存的语句,建议使用SQL_NO_CACHE
  • query_cache_wlock_invalidate:如果某表被其它的会话锁定,是否仍然可以从查询缓存中返回结果,默认值为OFF,表示可以在表被其它的会话锁定的场景中继续从缓存返回数据;ON则表示不允许
  • query_cache_type:是否开启缓存功能,取值为ON,OFF,DEMAND

查询缓存

  • SELECT语句的缓存控制
    SQL_CACHE:显示指定存储查询结果于缓存之中
    SQL_NO_CACHE:显示查询结果不予缓存
  • query_cache_type参数变量:
    query_cache_type的值为OFF或0时,查询缓存功能关闭
    query_cache_type的值为ON或1时,查询缓存功能打开,SELECT的结果符合缓存条件即会缓存,否则,不予缓存,显示指定SQL_NO_CACHE,不予缓存,此为默认值
    query_cache_type的值为DEMAND或2时,查询缓存功能按需进行,显示指定SQL_CACHE的SELECT语句才会缓存;其它均不予缓存
  • 参看:https://mariadb.com/kb/en/library/server-system-variables/#query_cache_type
    https://dev.mysql.com/doc/refman/5.7/en/query-cache-configuration.html
查询缓存相关的状态变量:

SHOW GLOBAL STATUS LIKE 'Qcache%';

  • Qcache_free_blocks:处于空闲状态Query Cache中内存Block数
  • Qcache_free_memory:处于空闲状态的Query Cache内存总量
  • Qcache_hits:Query Cache命中次数
  • Qcache_inserts:向Query Cache中插入新的Query Cache的次数,即没有命中的次数
  • Qcache_lowmem_prunes:当Query Cache 内存容量不够,需要删除老的Query Cache以给新的Cache对象使用的次数
  • Qcache_not_cached:没有被Cache的SQL数,包括无法被Cache的SQL以及由于query_cache_type设置的不会被Cache的SQL语句
  • Qcache_queries_in_cache:在Query Cache中的SQL数量
  • Qcache_total_blocks:Query Cache中总的Block

命中率和内存使用率估算

  • 查询缓存中内存块的最小分配单位query_cache_min_res_unit:
    (query_cache_size - Qcache_free_memory) / Qcache_queries_in_cache
  • 查询缓存命中率:
    Qcache_hits / (Qcache_hits + Qcache_inserts) * 100%
  • 查询缓存内存使用率:
    (query_cache_size - qcache_free_memory) / query_cache_size * 100%

InnoDB存储引擎的缓冲池:

通常InnoDB存储引擎缓存池的命中不应该小于99%

查看相关状态变量:

SHOW GLOBAL STATUS LIKE 'innodb%read%'\G;

  • Innodb_buffer_pool_reads:表示从物理磁盘读取页的次数
  • Innodb_buffer_pool_read_ahead:预读的次数
  • Innodb_buffer_pool_read_ahead_evicted:预读页,但是没有读缓冲池中被替换的页数量,一般用来判断预读的效率
  • Innodb_buffer_pool_read_requests:从缓存池中读取页次数
  • Innodb_data_read:总共读入的字节数
  • Innodb_data_reads:发起读取请求的次数,每次读取可能需要读取多个页

SQL语句性能优化

  • 查询时,能不用*就不用*,尽量写全字段名
  • 大部分情况连接效率远大于子查询
  • 多表连接时,尽量小表驱动大表,即小表 join 大表
  • 在千万级分页时使用 limit
  • 对于经常使用的查询,可以开启缓存
  • 多使用 explain 和 profile 分析查询语句
  • 查看慢查询日志,找出执行时间长的 sql 语句优化

你可能感兴趣的:(MySQL数据库性能优化)