众所周知,系统读取数据时,从内存中读取要比从硬盘上速度要快好几百倍。故如今绝大部分应用系统,都会最大程度的使用缓存(内存中的一个存储区域),来提升系统的运行效率。MySQL数据库也不例外。在这里,笔者将结合本身的工做经验,跟你们探讨一下,MySQL数据库中缓存的管理技巧:如何合理配置MySQL数据库缓存,提升缓存命中率。数据库

合理配置MySQL缓存 提升缓存命中率

  1、何时应用系统会从缓存中获取数据?缓存

  数据库从服务器上读取数据时,能够从硬盘的数据文件中获取数据,也能够从数据库缓存中读取数据。如今数据库管理员须要搞清楚的是,在什么样的状况下,系统是从缓存中读取数据,而不是从硬盘的数据文件中读取数据?服务器

  简单的说,数据缓存就是内存中的一块存储区域,其存储了用户的SQL文本以及相关的查询结果。一般状况下,用户下次查询时,若是所使用的SQL文本是相同的,而且自从上次查询后,相关的纪录没有被更新过,此时数据库就直接采用缓存中的内容。从这个原则中,能够看到若是要直接使用缓存中的数据,至少要知足如下几个条件。并发

  一是所采用的SQL文本是相同的。当先后两次用户使用了相同的SQL语句(假设不考虑其余条件),则服务器会从缓存中读取结果,而不须要再去解析和执行SQL语句。这里须要注意的是,这里的SQL文本必须一次不差的彻底相同。若是先后两次查询,使用了不一样的查询条件。如第一次查询时没有输入Where条件语句。后来发现数据量过多,利用了Where条件了过滤查询的结果。此时即便最后的查询结果是相同的,系统仍然是从数据文件中获取数据,而不是从数据缓存中。再如,Select后面所使用的字段名称也必须是相同的。若是有一个字段名称不一样或者先后两次查询所使用的字段数量不一样,则系统都会认为是不一样的SQL语句,而从新解析并查询。工具

  二是从数据缓存的角度考虑,大小写是不敏感的。如先后两次查询时,采用的字段名称可能只有大小写的差别。如第一次使用的是大小,第二次使用的是小写,这系统认为仍然是相同的SQL语句。或者说关键字大小写等等这都是不敏感的。性能

  三是要知足二次查询之间,数据记录包括表结构都没有被更改过。若是记录所在的标更改了,如增长了一个字段等等,此时使用这个表的全部缓冲数据系统将自动清空。这里须要注意,这里指的更改是一个广义的更改,包括表中任何数据或者结果的改变。举一个简单的例子,第一次查询时用户须要查询2010年的出货数据。查询后有用户在这个表中插入了一条2011年1月份的出货信息。而后又有用户须要查询2010年的出货信息。使用的SQL语句与第一次查询时彻底相同。在这种状况下,数据库系统会使用缓存中的数据吗?答案是否认的。由于当中间用户插入一条记录时,系统会自动清空跟这个表相关的全部缓存记录。当第二次查询时,缓存中已经没有这张表对应的缓存信息。此时就须要从新解析并查询。操作系统

  四是须要注意,默认字符集对缓存命中率的影响。一般状况下,若是客户端与服务器之间所采用的默认字符集不一样,则即便查询语句相同、在两次查询之间记录与表结构也没有被更改,系统仍然认为是不一样的查询。对于这一点须要特别的注意,你们比较容易忽视。内存

  2、提升缓存命中率的建议。class

  从上面的条件分析中能够看出,利用缓存中的数据具备比较严格的条件。其实这些条件也是合情合理的。主要是为了保障数据的一致性。对以上这些条件有深刻的认识以后,如今数据库管理员须要考虑的是,如何来提升这个缓存的命中率?对此笔者有以下几个建议。效率

  一是在配置时,客户端与服务器端要使用相同的字符集。若是客户端(或者说第三方工具)与服务器端使用的字符集不一样,那么任何状况下都不会使用缓存功能。特别在国内,须要用到中文的字符集。此时特别须要注意,客户端默认字符集要与服务器端的默认字符集相同。注意,这里是相同,而不是兼容。有时候即便采用了不一样的字符集,客户端上仍然能够正常显示。这主要是由于有些字符集虽然不相同,可是是相互兼容的。在缓存管理上,须要相同,光兼容还不行。

  二是在客户端上,要固化查询的语句。如如今有财务人员和采购人员同时从系统中查询11月份的出货数据。显然他们岗位职责不一样,所须要字段的内容是不一样的。此时在客户端出,能够容许用户设置本身所须要的表单格式。可是笔者建议,后台所采用的SQL语句最好是相同的。这里数据会通过三个渠道:后台数据库、客户端、用户。笔者的意识时,后台数据库与客户端之间的交互采用相同的SQL语句。而后客户端与用户之间进行交互时,根据用户定义的格式(包括字段先后的排列、不包括查询条件语句的差别)向用户显示数据。此时因为采用了相同的SQL语句(只是用户对于显示格式的要求不一样),从而能够提升应用系统的查询效率。

  三是提升内存中缓存的配置,来提升命中率。通常在服务器启动时,操做系统会跟数据库软件协商缓存空间的大小。当缓存工做不足时,缓存中最旧的缓存记录会被最新的消息所覆盖。可见,若是可以提升缓存空间,就能够提升命中率。这就好像打靶,目标多了,命中的概率也会高许多。不过用户的并发数越多,这个设置的效果会越不明显。

  四是经过分区表能够提升缓存的命中率。在上面的条件分析中,你们能够看到,只要所查询的表中插入了一条记录,系统就会清空缓存记录。如今以查询出货记录为例。出货记录表天天都在更新,而用户在年初时,会常常须要查询上一年的出货记录。此时因为这个表中的数据每一个小时都在更新,那么缓存中的信息会不断的被状况。此时缓存的命中率显然不会很高。针对这种状况,笔者建议能够采用分区表。如能够经过系统设置,将2010年的出货记录单独存放在一个出货的分区表中。即每个年度都使用一张单独的分区表。此时2011年的纪录,就不会影响到2010年的分区表。此时若是用户重复查询2010年的出货信息,只要其使用的SQL语句相同(没有采用不一样的查询条件),那么就能够享受缓存机制所带来的效益,提升应用系统的查询效果。。

  3、多个应用对缓存的影响。

  一般状况下,MySQL数据库的缓存是根据服务器内存的大小自动分配的。若是一台服务器上只有一个MySQL应用,那么当然最好。不过在实际工做中,为了下降信息化投资的成本,每每会在同一台服务器上布置多个信息化应用。因为其余信息化应用也须要使用内存的空间做为缓存,那么MySQL数据库中缓存空间就可能变小。若是遇到这种状况下,数据库管理员须要跟系统工程师进行协商,为各类不一样的应用根据性能要求的不一样,手工设置不一样的缓存空间。如此的话,就能够避免同一台服务器上不一样信息化应用对缓存的冲突。