Linux九阴真经之九阴白骨爪残卷10(MySQL架构、缓存及索引)
一、MySQL的架构
- 连接器
- 连接池,安全认证、线程池、连接限制、检查内存、缓存
- SQL接口 DML、DDL
- SQL解析器,对SQL语句的权限检查、解析为二进制程序
- 优化器,优化访问路径
- 缓存cache,buffer
- 存储引擎 innodb
- 文件系统
- 日志
二、查询缓存(Query Cache)
- SQL语句
- 查询缓存
- 解析器
- 解析树
- 预处理
- 查找最好的查询路径
- 查询优化SQL语句
- 执行计划
- API调用存储引擎
调用数据,返回结果
缓存SELECT操作或预处理查询的结果集和SQL语句,当有新的SELECT语句或预处理查询语句请求,先去查询缓存,判断是否存在可用的记录集,判断标准:与缓存的SQL语句,是否完全一样,区分大小写。
不需要对SQL语句做任何解析和执行,当然语法解析必须通过在先,直接从Query Cache中获得查询结果,提高查询性能
查询缓存的判断规则,不够智能,也即提高了查询缓存的使用门槛,降低其效率;查询缓存的使用,会增加检查和清理Query Cache中记录集的开销
哪些查询可能不会被缓存:
- 查询语句中加了SQL_NO_CACHE参数;
- 查询语句中含有获得值的函数,包含自定义函数,如:NOW()、CURDATE()、GET_LOCK()、RAND()、CONVERT_TZ()等;
- 对系统数据库的查询:mysql、information_schema 查询语句中使用SESSION级别变量或存储过程中的局部变量;
- 查询语句中使用了LOCK IN SHARE MODE、FOR UPDATE的语句,查询语句中类似SELECT …INTO 导出数据的语句;
- 对临时表的查询操作;存在警告信息的查询语句;不涉及任何表或视图的查询语句;某用户只有列级别权限的查询语句;
- 事务隔离级别为Serializable时,所有查询语句都不能缓存。
查询缓存相关的服务器变量:
- query_cache_min_res_unit: 查询缓存中内存块的最小分配单位,默认4k,较小值会减少浪费,但会导致更频繁的内存分配操作,较大值会带来浪费,会导致碎片过多,内存不足;
- query_cache_limit:单个查询结果能缓存的最大值,默认为1M,对于查询结果过大而无法缓存的语句,建议使用SQL_NO_CACHE;
- query_cache_size:查询缓存总共可用的内存空间;单位字节,必须是1024的整数倍,最小值40KB,低于此值有警报;
- query_cache_wlock_invalidate:如果某表被其它的会话锁定,是否仍然可以从查询缓存中返回结果,默认值为OFF,表示可以在表被其它会话锁定的场景中继续从缓存返回数据;ON则表示不允许;
- query_cache_type: 是否开启缓存功能,取值为ON, OFF, DEMAND,默认值为ON
- 值为OFF或0时,查询缓存功能关闭;
- 值为ON或1时,查询缓存功能打开,SELECT的结果符合缓存条件即会缓存,否则,不予缓存,显式指定SQL_NO_CACHE,不予缓存;
- 值为DEMAND或2时,查询缓存功能按需进行,显式指定SQL_CACHE的SELECT语句才会缓存;其它均不予缓存。
MariaDB [(none)]> SHOW VARIABLES LIKE 'query_cache%'; +------------------------------+----------+ | Variable_name | Value | +------------------------------+----------+ | query_cache_limit | 1048576 | | query_cache_min_res_unit | 4096 | | query_cache_size | 33554432 | | query_cache_strip_comments | OFF | | query_cache_type | ON | | query_cache_wlock_invalidate | OFF | +------------------------------+----------+
优化查询缓存:
查询缓存相关的状态变量:
- 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。
MariaDB [(none)]> SHOW GLOBAL STATUS LIKE 'Qcache%'; +-------------------------+----------+ | Variable_name | Value | +-------------------------+----------+ | Qcache_free_blocks | 1 | | Qcache_free_memory | 33536824 | | Qcache_hits | 0 | | Qcache_inserts | 0 | | Qcache_lowmem_prunes | 0 | | Qcache_not_cached | 4 | | Qcache_queries_in_cache | 0 | | Qcache_total_blocks | 1 | +-------------------------+----------+
命中率和内存使用率估算:
- 查询缓存中内存块的最小分配单位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%
三、索引
索引是特殊数据结构:定义在查找时作为查找条件的字段,索引实现在存储引擎。
- 索引可以降低服务需要扫描的数据量,减少了IO次数
- 索引可以帮助服务器避免排序和使用临时表
- 索引可以帮助将随机I/O转为顺序I/O
- 但是占用额外空间,影响插入速度
1、索引类型:
- B + Tree 索引:顺序存储,每一个叶子节点到根的距离都是相同的,左前缀索引,适合查询范围类的数据;
- 适合使用B-Tree索引的查询类型
- 全值匹配
- 匹配最左前缀
- 匹配范围值
- 精确匹配某一列并范围匹配另一列(复合索引)
- 只访问索引的查询 - 不适合使用B-tree索引的查询类型
- 不从最左列开始
- 不能跳过索引中的列
- 如果查询中某个列是为范围查询那么右侧的列无法再使用索引优化查询
- 适合使用B-Tree索引的查询类型
Hash索引:基于哈希表,构建出键值对的索引,特别适用于精确匹配索引中的索引列,只支持等值比较查询(IN,=,<>);不适合于顺序查询,不支持模糊匹配;只有Memory存储引擎支持显式Hash索引
空间索引(R - Tree):只有MyISAM支持空间索引
全文索引(FULL TEXT):在文本中查找关键词
2、高性能索引策略:
- 独立使用列,尽量避免其参与运算
- 使用左前缀索引:索引构建于字段的左侧的多少字符要通过索引选择性来评估;索引选择性:不重复的索引值和数据表的记录总数的比值
- 多列索引:AND操作时更适合使用多列索引,而非为每个列创建单独的索引
- 选择合适的索引列次序:无排序和分组时,将选择性最高放左侧
3、索引的优化建议
- 只要列中含有NULL值,就最好不要在此例设置索引,复合索引如果有NULL值,此列在使用时也不会使用索引
- 尽量使用短索引,如果可以,应该制定一个前缀长度
- 对于经常在where子句使用的列,最好设置索引
- 对于有多个列where或者order by子句,应该建立复合索引
- 对于like语句,以%或者‘-’开头的不会使用索引,以%结尾会使用索引
- 尽量不要在列上进行运算(函数操作和表达式操作)
- 尽量不要使用not in和<>操作
- 多表连接时,尽量小表驱动大表,即小表 join 大表
- 在千万级分页时使用limit
- 对于经常使用的查询,可以开启缓存
- 大部分情况连接效率远大于子查询
4、索引的创建与删除
- 创建索引
CREATE INDEX index_name ON tbl_name (index_col_name,...);
MariaDB [hellodb]> CREATE INDEX index_name ON students(name); #创建简单索引 MariaDB [hellodb]> CREATE INDEX index_name_age ON students(name,age); #创建复合索引
- 查看索引
SHOW INDEXES FROM [db_name.]tbl_name;
MariaDB [hellodb]> SHOW INDEX FROM students\G
- 删除索引
DROP INDEX index_name ON tbl_name;
MariaDB [hellodb]> DROP INDEX index_name ON students;
- 优化表空间
MariaDB [hellodb]> OPTIMIZE TABLE students;
- 查看索引使用的情况
启用记录索引使用情况:SET GLOBAL userstat=1;
查看索引使用情况:SHOW INDEX_STATISTICS;
我们可以统计不经常使用的索引从而进行优化
四、EXPLAIN命令
通过EXPLAIN来分析索引的有效性:EXPLAIN SELECT clause
,获取查询执行计划信息,用来查看查询优化器如何执行查询
MariaDB [hellodb]> EXPLAIN SELECT name FROM students WHERE name = 'Lin Daiyu'\G *************************** 1. row ***************************id: 1select_type: SIMPLEtable: studentstype: ref possible_keys: index_name_agekey: index_name_agekey_len: 152ref: constrows: 1Extra: Using where; Using index
- id:当前查询语句中,每个SELECT语句的编号;复杂类型的查询有三种:简单子查询、用于FROM子句中的子查询、联合查询(UNION,注意:UNION查询的分析结果会出现一个额外匿名临时表)
- select_type:
- SIMPLE :简单查询
- SUBQUERY: 简单子查询
- PRIMARY:最外面的SELECT
- DERIVED: 用于FROM中的子查询
- UNION:UNION语句的第一个之后的SELECT语句
- UNION RESULT: 匿名临时表
- table:SELECT语句关联到的表
- type:关联类型或访问类型,即MySQL决定的如何去查询表中的行的方式,以下顺序,性能从低到高
- ALL: 全表扫描
- index:根据索引的次序进行全表扫描;如果在Extra列出现“Using index”表示了使用覆盖索引,而非全表扫描
- range:有范围限制的根据索引实现范围扫描;扫描位置始于索引中的某一点,结束于另一点
- ref: 根据索引返回表中匹配某单个值的所有行
- eq_ref:仅返回一个行,但与需要额外与某个参考值做比较
- const, system: 直接返回单个行
- possible_keys:查询可能会用到的索引
- key: 查询中使用到的索引
- key_len: 在索引使用的字节数
- ref: 在利用key字段所表示的索引完成查询时所用的列或某常量值
- rows:MySQL估计为找所有的目标行而需要读取的行数
- Extra:额外信息
- Using index:MySQL将会使用覆盖索引,以避免访问表
- Using where:MySQL服务器将在存储引擎检索后,再进行一次过滤
- Using temporary:MySQL对结果排序时会使用临时表
- Using filesort:对结果使用一个外部索引排序
五、SQL语句性能优化
- 查询时,能不要*就不用*,尽量写全字段名
- 大部分情况连接效率远大于子查询
- 多表连接时,尽量小表驱动大表,即小表 join 大表
- 在千万级分页时使用limit
- 对于经常使用的查询,可以开启缓存
- 多使用explain和profile分析查询语句
- 查看慢查询日志,找出执行时间长的sql语句优化
转载于:https://www.cnblogs.com/huxiaojun/p/9175253.html
Linux九阴真经之九阴白骨爪残卷10(MySQL架构、缓存及索引)相关推荐
- Linux九阴真经之九阴白骨爪残卷15
一.MySQL复制相关概念 1.主从复制:主节点将数据同步到多个从节点 2.级联复制:主节点将数据同步到一个从节点,其他的从节点在向从节点复制数据 3.同步复制:将数据从主节点全部同步到从节点时才返回 ...
- Linux九阴真经之九阴白骨爪残卷9(存储引擎MyISAM、MySQL服务器变量)
一.MyISAM存储引擎 缺点: 不支持事务 最小粒度锁:表级 读写相互阻塞,写入不能读,读时不能写 不支持MVCC(支持多版本并发控制机制) 不支持聚簇索引 不支持数据缓存 不支持外键 崩溃恢复性较 ...
- Linux九阴真经之九阴白骨爪残卷12(日志功能)
一.事务日志 transaction log:事务型存储引擎自行管理和使用 在一个事务提交后还没有存到磁盘的情况下会记录到事务日志,这个时候如果系统断电,再次开机后会自动将已提交的事务重做(redo ...
- Linux九阴真经之九阴白骨爪残卷2(SSH)
SSH ssh:安全的远程登录 两种方式的用户登录认证 基于passwork 基于key 客户端 常见的客户端工具有:Windows版的putty.securecrt.xshell:linux中有ss ...
- Linux九阴真经之九阴白骨爪残卷13(LVM的备份还原,恢复最新状态)
一.备份策略 1.备份的类型 类型1: 热备份:读写不受影响(MyISAM不支持热备,InnoDB支持热备) 温备份:仅可以执行读操作 冷备份:离线备份,读写操作均中止 类型2: 物理备份:复制数据文 ...
- Linux九阴真经之九阴白骨爪残卷16
一.加密传输复制的实现 在默认的主从复制过程或远程连接到MySQL/MariaDB所有的链接通信中的数据都是明文的,外网里访问数据或则复制,存在安全隐患.通过SSL/TLS加密的方式进行复制的方法,来 ...
- Linux九阴真经之九阴白骨爪残卷14(备份和恢复)
备份还原案例 前提:log_bin=ON 一.早上上班后误删数据库,如何恢复最新状态 1.假设早上已经完成备份 (开启二进制),然后在students表里新增了一条数据 [root@centos7 ~ ...
- Linux九阴真经之九阴白骨爪残卷7(Mariadb的三种安装方法)
Mariadb 的安装方法 一.yum安装 二.编译安装 三.二进制安装 一.yum安装方法 1.yum直接安装,也可以登录官网,指定新版(10.2)安装 https://downloads.mari ...
- Linux九阴真经之九阴白骨爪残卷8(存储函数、存储过程、触发器)
存储函数 说明: 参数可以有多个,也可以没有参数,必须有且只有一个返回值. 1.系统函数 参考官方文档:https://dev.mysql.com/doc/refman/5.7/en/func-op- ...
最新文章
- [原]Python命令
- Linux 在脚本里面启动终端并执行命令
- 零基础实践深度学习之数学基础
- Java中Lambda表达式与方法引用和构造器引用
- Docker部署SpringBoot的两种方法,后一种一键部署超好用!
- 修改系统Documents and Settings目录的位置
- mib 文件中的 rowstatus 参数_k8s yaml格式的pod定义文件详解
- react 中组件隐藏显示_React组件开发中常见的陷阱及解决
- 简书首页标题配图bug,偶发,未能重现(可以重现2017-12)
- PHP学习笔记二(面向对象和表单)
- OpenCV3.0.0 + VS2012 的环境搭建
- javascript new对象的过程
- 金融风控系统设计 - 外汇管理风控系统
- 企业信息与网络通信安全 团队成员简历-叶俊
- 安卓手机续航测试软件,10款手机电池续航测试对决:都是骁龙865手机,续航差距有多大?...
- 微软官方的精简版Windows 7——Windows Thin PC
- Mac自带的录屏功能
- diy nas配置推荐2019_5款NAS 系统横向测评,看看哪款最适合你!
- 网络语言进课堂:上海禁止北京面对
- 在 Kubernetes 上执行 GitHub Actions 流水线作业