QueryCache那些事

来源:互联网 发布:淘宝链接生成器 编辑:程序博客网 时间:2024/06/07 18:27


上一节我们说到 Myql通信就像踢足球一样,发了请求之后只能等待命令执行完成才能重新掌握主动权。这一节我们主要说下,Mysql为了更快的返回结果做了什么?


 

QueryCache

在解析一个查询语句之前,如果查询缓存是打开的,Mysql会优先解析这个查询是否命中查询缓存中的数据。这个查找主要是通过一个对大小写敏感的Hash查找,如果查询与缓存中的查询有一个字节的不同都无法命中。

当查询命中缓存,Mysql会立即返回结果,跳过解析、优化、执行阶段。(这当然是最快的,不过当查询的表数据发生变化时,是无法命中的)。

如何判断命中

缓存存放在一个引用表中,通过Hash值引用,这个Hash包含了:查询本身、当前查找的数据库、客户端协议的版本等信息。 当判断缓存是否命中时,Mysql直接使用SQL语句和客户端发来的原始信息,所以任何字符的不同(如空格、注释等)都会导致缓存的不命中。

除此之外,当查询包括不确定的数据时,如Now()或者Current_Date()查询结果时不会缓存的。其实这也很容易理解,因为Now()函数的值一直变化,所以实际查询的SQL也会一直发生变化,所以时无法缓存的。事实上包含任何用户的自定义函数、存储过程、用户变量等都不会缓存(不会缓存的真多)

其实总结一句话就是:查询结果包含任何不确定的函数,那么查询缓存中是不可能找到结果的。需要注意的是,判断缓存是否命中是发生在SQL解析之前的事情,所以在执行查询缓存之前,Mysql是不知道SQL是否有变化函数的。

所以这就涉及到一个优化的点便是:

    datediff(current_date,interval 1 day)  不会cache,

    datediff(‘2016-07-11’,interval 1 day)  是会被cache的

(前提是query_cache已经打开)

凡事皆有利弊,提高查询速度本身便会带来一些其他的开销。

QueryCache的消耗

1、查询之前必须判断是否有缓存

2、假设一个可以缓存的SQL执行完成之后,Mysql发现这些数据没有被缓存,其将结果存入查询缓存中,这部分会带来一部分开销

3、对写也有一定的影响,因为当数据库中表写入数据时,Mysql需要将对应表的缓存标志失效。当查询缓存较大时或者随便较多时,会引起很大的内存消耗。特别是当缓存使用了很大的内存,缓存的失效可能会导致系统Hang住。

并且当使用InnoDB时,事务的一些特性会限制查询缓存的使用。当事务中某个语句修改某个表时,这个表的缓存会被设置失效。所以长时间的事务会降低查询缓存的命中率,因为这个表的所有查询都不会缓存:)

说了这么多QueryCache 到底是什么原理呢?内存是怎么分配的呢?如何正确的使用可以带来最大的性能提升呢,让我们下一章来扒一扒。

To be continue…

上一节我们说到 Myql通信就像踢足球一样,发了请求之后只能等待命令执行完成才能重新掌握主动权。这一节我们主要说下,Mysql为了更快的返回结果做了什么?


 

QueryCache

在解析一个查询语句之前,如果查询缓存是打开的,Mysql会优先解析这个查询是否命中查询缓存中的数据。这个查找主要是通过一个对大小写敏感的Hash查找,如果查询与缓存中的查询有一个字节的不同都无法命中。

当查询命中缓存,Mysql会立即返回结果,跳过解析、优化、执行阶段。(这当然是最快的,不过当查询的表数据发生变化时,是无法命中的)。

如何判断命中

缓存存放在一个引用表中,通过Hash值引用,这个Hash包含了:查询本身、当前查找的数据库、客户端协议的版本等信息。 当判断缓存是否命中时,Mysql直接使用SQL语句和客户端发来的原始信息,所以任何字符的不同(如空格、注释等)都会导致缓存的不命中。

除此之外,当查询包括不确定的数据时,如Now()或者Current_Date()查询结果时不会缓存的。其实这也很容易理解,因为Now()函数的值一直变化,所以实际查询的SQL也会一直发生变化,所以时无法缓存的。事实上包含任何用户的自定义函数、存储过程、用户变量等都不会缓存(不会缓存的真多)

其实总结一句话就是:查询结果包含任何不确定的函数,那么查询缓存中是不可能找到结果的。需要注意的是,判断缓存是否命中是发生在SQL解析之前的事情,所以在执行查询缓存之前,Mysql是不知道SQL是否有变化函数的。

所以这就涉及到一个优化的点便是:

    datediff(current_date,interval 1 day)  不会cache,

    datediff(‘2016-07-11’,interval 1 day)  是会被cache的

(前提是query_cache已经打开)

凡事皆有利弊,提高查询速度本身便会带来一些其他的开销。

QueryCache的消耗

1、查询之前必须判断是否有缓存

2、假设一个可以缓存的SQL执行完成之后,Mysql发现这些数据没有被缓存,其将结果存入查询缓存中,这部分会带来一部分开销

3、对写也有一定的影响,因为当数据库中表写入数据时,Mysql需要将对应表的缓存标志失效。当查询缓存较大时或者随便较多时,会引起很大的内存消耗。特别是当缓存使用了很大的内存,缓存的失效可能会导致系统Hang住。

并且当使用InnoDB时,事务的一些特性会限制查询缓存的使用。当事务中某个语句修改某个表时,这个表的缓存会被设置失效。所以长时间的事务会降低查询缓存的命中率,因为这个表的所有查询都不会缓存:)

说了这么多QueryCache 到底是什么原理呢?内存是怎么分配的呢?如何正确的使用可以带来最大的性能提升呢,让我们下一章来扒一扒。

To be continue…

0 0