1
MariaDB查询缓存
缓存中的数据是开源形式的,以键值对(k/v)的形式存在
key:查询语句的hash值;
value:查询语句的查询结果;
缓存中的数据主要是经过整个查询语句的hash值的比较,彻底相同则命中;这样经过缓存响应客户端请求,能够提升检索效率;固然,也不是全部的查询数据均可以缓存,那么哪些数据不可以缓存呢?mysql
1.要查询的数据库中可能包含敏感信息;如MySQL数据库中的各系统表;
2.在查询语句中包含有用户自定义的函数(UDF)
3.存储函数;
4.用户自定义变量;
5.对于临时表发起的查询请求;
6.包含列级别受权的查询;
7.有着不肯定结果值的mysql的内键函数;如:NOW(),CURRENT_DATE(),CURRENT_TIME(),CURRENT_USER(),...
与查询缓存相关的服务器参数:算法
MariaDB [hellodb]> show global variables like 'query_cache%';
+------------------------------+---------+
| Variable_name | Value |
+------------------------------+---------+
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 0 |
| query_cache_strip_comments | OFF |
| query_cache_type | ON |
| query_cache_wlock_invalidate| OFF |
+------------------------------+---------+
query_cache_limit:可以缓存查询结果的最大字节数上限;(单语句结果集的上限)
在使用SELECT查询语句时,应尽可能避免"SELECT *"查询方式的应用,同时须要WHERE子句或HAVING子句对查询结果进行优化处理;以使得查询结果尽量精确;
对于哪些有着较大的查询结果集的语句,应该在SELECT中明确显式的使用SQL_NO_CACHE参数,以免查询结果先如缓存再移除缓存;sql
query_cache_min_res_unit:查询缓存中,内存块的最小分配单元;能够比较有效的避免内存碎片;
较大的变量值可能会带来内存空间浪费;
较小的变量值会减小内存空间浪费,但会致使更加频繁的内存分配和回收操做;长期下来必然产生内存碎片;数据库
query_cache_size:查询缓存申请的在内存中的总可用空间;
单位是字节,设定的值必须是1024的整数倍;缓存
query_cache_strip_comments:用于控制是否去掉SQL查询语句中的注释部分以后再做为key部分存入查询缓存;
默认值是"OFF",若是启用,插入查询缓存中的查询语句是不带有注释部分信息的服务器
query_cache_type:缓存功能开启与否的开关;
ON:启用;仅不缓存"SQL_NO_CACHE"参数的查询结果;
OFF:停用缓存;
DEMAND:按需缓存;默认不缓存,仅缓存"SQL_CACHE"参数的查询结果;数据结构
query_cache_wlock_invalidate:若是某个链接会话对某表施加了写锁,是否依然能够从缓存中查询并返回查询结果;
默认值为"OFF",表示能够;
ON,表示不能够;
1
与查询缓存相关的服务器参数:
image.png
Qcache_free_blocks:表示查询缓存中目前还剩余多少个blocks;若是该值显示较大,则说明查询缓存中内存碎片过多;ide
Qcache_free_memory:查询缓存中还空闲的内存空间;
经过此状态参数能够评估当前系统中的查询缓存的使用状况;
若是剩余量过小,且剩余块不少,大量的内存空间均以碎片形式存在;
若是剩余量过小,且剩余块很少,分配的查询缓存的内存空间恰好或略有欠缺;
若是剩余量较大,分配的查询缓存的内存空间太多,应进行相应调整;一旦调整了缓存大小,则其中存放的查询结果会当即清除;函数
Qcache_hits:表示查询缓存中查询语句的命中次数;数字越大缓存效果越理想;性能
Qcache_inserts:表示未命中的然后通过处理将查询结果添加至查询请求的数量;
数值越大,则证实查询缓存效果越不理想;
能够经过规范书写查询请求的SQL语句减小此类查询请求的数量;
注意:若是查询缓存中确实没有对应查询语句的查询缓存,此数值的增长也是正常现象;
Qcache_lowmem_prunes:该参数记录了有多少条查询请求是由于内存空间不足而基于LRU算法被移除缓存的;若是该数值过大,则表示分配的内存空间过小;
Qcache_not_cached:取决于query_cache_type变量的设置的做用下,没有被缓存的查询请求的数量;
Qcache_queries_in_cache:当前查询缓存中缓存的查询请求的结果的数量;
Qcache_total_blocks:当前查询缓存中总计分配了多少个block;
查询缓存命中率的计算:Qcache_hits/( Qcache_hits + Qcache_inserts )
注意:若是对表进行了写操做,例如增删改等操做,则MySQL会自动将查询缓存中与该表相关的缓存项所有清除;所以与此表有关的查询请求必须从新构建缓存内容;
1.尽量批量写入(构建自定义过程;启用事务),尽可能减小屡次的单写入操做;
2.缓存空间不宜设置过大,若是大量缓存同时失效,会使得MySQL的执行引擎压力剧增,可能会致使服务器假死;
3.必要时,须要使用SQL_CACHE和SQL_NO_CACHE等SELECT语句中的参数来手动控制缓存存入与否;
4.对于密集型写操做应用场景来讲,禁用缓存功能可能提高服务器性能;
接下来作个实例:
1.首先要保证query_cache_type开启:
image.png
2.为缓存空间设置一个大小
image.png
image.png
image.png
3.查询一下某个数据的数据表;
image.png
//在状态参数中未命中出现一次,由于没有缓存;而且此次查询完成后,缓存了一条信息;
image.png
4.再次进行与上次查询同样的查询;
//此次hits段命中了一次;你能够屡次查询查看命中次数;
image.png
image.png
1
MySQL的索引
那么是为了什么而提出的索引呢,即索引的做用是什么呢:当MySQL中数据过多时,要求检索的速度也应该高,因此,为了提升检索速度,提出了索引这一律念;什么是索引:也就是指定的表中的数据子集;即:将表中某个或某些字段中的数据提取出来,另存为用一个特定数据结构进行组织的数据。
索引有不一样类型:FULLTEXT,SPACIAL,B+ TREE,HASH;因为存储引擎不一样,支持的索引的类型也不一样:
1
2
InnoDB存储引擎支持:B+ TREE,HASH;
MEMORY存储引擎:显示的支持HASH索引;
1.全键值匹配:精确匹配某个值;
select ... where Name='Xu Wenlong'
2.左前缀匹配:值精确到数据起始位置的一部分:
select ... where Name like 'G%'
3.区间数据的连续数值匹配,一般用于BETWEEN...AND...环境中:
select ... where age between 30 and 50;
4.区间数据的离散值匹配;一般用于IN列表环境或OR列表环境;也是精确值匹配;
select ... where StuID IN (1,3,7)
5.精确匹配左列,范围匹配右侧其余列;
select ... where StuID > 10 and name like 'a%';
6.对于覆盖索引的查询请求:
1.若是查询条件不是精确从最左侧列开始的,索引无效;
对StuID字段作索引,select ... where Name like 'A%' and StuID>10;
2.若是索引了多列,若跳过索引中的某列,索引无效:
对StuID,Name,Age作索引,select ... where StuID>10 and Age>20;
3.若是索引了多列,且在查询语句中对某个列作范围匹配,则其右侧列不能再使用索引优化查询;
对StuID,Name,Age作索引,select ... where StuID>10 and Name like 'a%';
1
HASH索引:基于HASH表实现的索引;很是适用于值的精确匹配的查询请求;
适用的场景:只支持等值比较查询:如:=,IN(),<=>(NULL safe equal());
不适用场景:全部的非精确值的比较查询:
索引的优势:
1.较少须要扫描的数据总量,减小IO次数;
2.脚面对扫描的数据进行再次排序;
3.避免生成和使用临时表;
4.将随机IO转换成顺序IO;
定义索引的通常性规则:
1.选择用于索引的数据类型;
越小的数据类型越适于作索引;
越简单的数据类型越适于作索引;
尽可能避免该字段中出现"NULL"值;若是必需要使用空值;建议使用"0"或一个空的字符串或者某个承认的特殊值来代替"NULL"值;
2.选择主键的类型;
优先选择整型;
×××数据能够更快速被处理;并且可使用AUTO_INCREMENT修饰符避免重复数据;
尽可能避免使用字符型;
存储字符型数据须要消耗更多的空间,处理字符型数据须要消耗更多的CPU和内存资源,处理速度较慢;
高性能索引的定义策略:
1.在WHERE子句中以独立使用某列作判断条件为最佳,尽可能避免该列直接参数运算;
select ... where Age+2>10;
2.最左前缀索引:索引应该构建于字段的最左侧的一个或连续的多个字符;具体的选择数量能够经过"索引选择性"进行评估;
索引选择性:不重复的索引值和数据表的记录总数的比值;
3.多列索引的选择;
WHERE条件子句中使用AND运算符链接多个查询条件;尽可能避免使用OR运算符;
若是使用OR运算符,应该基于每一个列作单列索引;
4.选择合适的索引定义次序;选择性最高的列放在最左侧;
EXPLAIN语句
对索引进行分析,查看索引的应用信息;
用法:
EXPLAIN [explain_type] SELECT select_options
explain_type: EXTENDED | PARTITIONS
EXTENDED:显示扩展信息;
PARTITIONS:用于分区表;
下面来上一个例子:
image.png
我们对个字段来作个解释:
id:当前的查询语句中,各个SELECT语句的编号;
select_type:查询类型;
1
简单查询:SIMPLE //即经过交叉链接来查询;
image.png
1
复杂查询:
简单子查询(用于WHERE子句中的子查询):SUBQUERY
image.png
用于FROM语句中的子查询;DERIVED
image.png
联合查询中的第一个查询:PRIMARY
联合查询中其余的查询:UNION
image.png
联合查询时生成的临时表查询:UNION RESULT
image.png
table:当前的查询语句所针对的表;
type:关联类型,或称为访问类型;也能够理解为MySQL是如何查询表中的行;
ALL:全表扫描;,MySQL将遍历全表以找到能够匹配的行;
index:全表扫描,与ALL所不一样的是index类型只是遍历索引树;
range:索引范围扫描,对索引的扫描从某一个点开始,返回匹配某一个值域的行;
一般能够基于指定的索引,WHERE子句使用IN列表、BETWEEN...AND...、或带有"=",">","<"等的查询;
ref:使用非惟一索引扫描或者使用惟一索引的左前缀扫描;返回匹配某个单独值的行;
eq_ref:相似于ref,区别就是使用惟一索引,对于每个索引键值,表中都只有一条记录匹配;不管是单表查询仍是多表查询,都使用主键或惟一键索引来做为关联条件;
const,system:当MySQL对查询部分进行优化,而且将优化结果转换为一个常量,使用const类型;
system类型是一个const类型特例,当要查询的表中只有一行时,使用system类型;
NULL:MySQL在优化过程当中分解查询语句,而执行时不用访问表或索引;
image.png
image.png
image.png
image.png
image.png
possible_keys:为了执行查询语句,MySQL可能使用哪一个索引在表中查找到记录;
若是查询所涉及到的字段上存在索引,则该索引会被列出,但不必定会被查询使用;
key:显示MySQL数据库在查询过程当中,实际使用到的索引;若是查询过程没有用到任何索引,则此处显示为"NULL";
key_len:表示索引中能够被引用的字节数;能够经过该列计算查询中使用的索引的长度;
注意:key_len显示的值一般为索引字段的最大可能长度,并非实际的使用长度;所以key_len是根据表定义时指定的字段长度计算获得的,而并非在表中经过检索数据获得的;
ref:在利用key字段所显示的索引完成查询操做时所引用的列或常量值;若是都没有则显示为"NULL";
rows:表示MySQL根据表统计信息及索引选用的状况,估算的本次检索所须要去查找到的全部记录的过程当中须要读取的表的行数;
Extra:额外信息,或称扩展信息;
Using where:表示MySQL服务器将在存储引擎检索后再次进行调校过滤;许多的where条件里涉及到索引中的列而且当MySQL读取该索引时,既能够被存储引擎检验;
Using index:使用了覆盖索引进行检索;
Using temporary:在查询过程当中使用了临时表来存放查询结果集;常见于排序或分组查询;
Using filesort:MySQL中没法利用索引完成排序操做就称为"文件排序";
Using join buffer:强调了在获取链接条件时没有使用到索引,而且须要链接缓冲区来存储中间结果。若是出现了该值,须要根据查询的具体状况适当的添加索引以提示查询性能;
Impossible where:若是该值出现,则意味着where子句没有发现符合条件的行;
Select tables optimized away:该值意味着仅经过使用索引来进行查询,可是优化器可能从聚合函数的结果中给出一个可行的优化方案;
Using sort-union(...)
Using union(...)
Using intersect(...)
上述状况多出现于在实现查询的过程当中,决定使用不止一个索引时;
filtered:从可选的行中再次过滤以后选择出最终的查询结果的比值;
image.png
image.png
image.png
EXPLAIN总结:1.EXPLAIN语句并不会告知关于触发器、存储过程相关的信息或用户自定义函数对查询的影响状况;2.EXPLAIN语句不会考虑任何Cache;3.EXPLAIN语句不会显示MySQL自身的执行查询时所做出的优化操做;4.部分统计信息并非精确值,而是估算结果;5.EXPLAIN语句只能分析解释SELECT语句,其余的暗含SELECT语句的操做;其余的非SELECT操做只有在重写为SELECT后,才能查看执行计划