zoukankan      html  css  js  c++  java
  • MYSQL查询缓存

    MySQL 查询缓存保留了查询返回给客户端的完整结果。当缓存命中的时候,服务器马上返回保存的结果,并跳过解析、优化和执行步骤。缓存也需要开销,只有在节省的资源大于开销的时候,缓存才是真正有效率的,这和服务器的负载相关。

    为了保证 Query Cache 中的内容与是实际数据绝对一致,当表中的数据有任何变化,包括新增,修改,删除等,都会使所有引用到该表的 SQL 的 Query Cache 失效。

    mysql>  SHOW VARIABLES LIKE '%query_cache%';

    +------------------------------+---------+

    | Variable_name                | Value   |

    +------------------------------+---------+

    | have_query_cache             | YES     |

    | query_cache_limit            | 1048576 |

    | query_cache_min_res_unit     | 4096    |

    | query_cache_size             | 9437184 |

    | query_cache_type             | ON      |

    | query_cache_wlock_invalidate | OFF     |

    +------------------------------+---------+

    6 rows in set (0.00 sec)

    各项参数的意义

    query_cache_limit:允许 Cache 的单条 Query 结果集的最大容量,默认是1MB,超过此参数设置的 Query 结果集将不会被 Cache

    query_cache_min_res_unit:设置 Query Cache 中每次分配内存的最小空间大小,也就是每个 Query 的 Cache 最小占用的内存空间大小

    query_cache_size:设置 Query Cache 所使用的内存大小,默认值为0,大小必须是1024的整数倍,如果不是整数倍,MySQL 会自动调整降低最小量以达到1024的倍数

    query_cache_type:控制 Query Cache 功能的开关,可以设置为0(OFF),1(ON)和2(DEMAND)三种,意义分别如下:

    0(OFF):关闭 Query Cache 功能,任何情况下都不会使用 Query Cache

    1(ON):开启 Query Cache 功能,但是当 SELECT 语句中使用的 SQL_NO_CACHE 提示后,将不使用Query Cache

    2(DEMAND):开启 Query Cache 功能,但是只有当 SELECT 语句中使用了 SQL_CACHE 提示后,才使用 Query Cache

    query_cache_wlock_invalidate:控制当有写锁定发生在表上的时刻是否先失效该表相关的 Query Cache,如果设置为 1(TRUE),则在写锁定的同时将失效该表相关的所有 Query Cache,如果设置为0(FALSE)则在锁定时刻仍然允许读取该表相关的 Query Cache。

     

    修改参数

    缓存大结果没有太大的益处。可以通过降低query_cache_limit 的值阻止缓存大结果,它有时有助于在碎片和在缓存中保存结果的开销中得到平衡。

    mysql> set global query_cache_limit=1024;

    Query OK, 0 rows affected (0.00 sec)

     

    mysql>  SHOW VARIABLES LIKE '%query_cache%';

    +------------------------------+---------+

    | Variable_name                | Value   |

    +------------------------------+---------+

    | have_query_cache             | YES     |

    | query_cache_limit            | 1024    |

    | query_cache_min_res_unit     | 4096    |

    | query_cache_size             | 9437184 |

    | query_cache_type             | ON      |

    | query_cache_wlock_invalidate | OFF     |

    +------------------------------+---------+

    6 rows in set (0.00 sec)

     

    MySQL 检查缓存命中的规则

    1、在检查缓存的时候,MySQL 不会对语句进行解析、正则化或者参数化,它精确地使用客户端传来的查询语句和其他数据。只要字符大小写、空格或者注释有一点点不同,查询缓存就认为这是一个不同的查询

    2、查询缓存不会存储有不确定结果的查询。因此,任何一个包含不确定函数(比如NOW()或CURRENT_DATE())的查询不会被缓存。同样地,CURRENT_USER()或CONNECTION_ID()这些由不同用户执行,将会产生不同的结果的查询也不会被缓存。事实上,查询缓存不会缓存引用了用户自定义函数、存储函数、用户自定义变量、临时表、mysql 数据库中的表或者任何一个有列级权限的表的查询

     

    开启查询缓存的开销

      读取查询在开始之前必须要检查缓存。

      如果查询是可以被缓存的,但是不在缓存中,那么在产生结果之后进行保存会带来一些额外的开销。

      写入数据的查询也会有额外的开销,因为它必须使缓存中相关的数据表失效。

    这些开销相对来说较小,所以查询缓存还是很有好处的。但是,稍后你会看到,额外的开销有可能也会增加。

    从缓存中受益最多的查询可能是需要很多资源来产生结果,但是不需要很多空间来保存的类型。所以用于存储、返回和失效的代价都较小。聚集查询,比如从大表中利用COUNT()产生较小的结果,就符合这个范畴。

     

    检查查询缓存使用情况

    检查是否从查询缓存中受益的最简单的办法就是检查缓存命中率

    当服务器收到SELECT 语句的时候,Qcache_hits 和Com_select 这两个变量会根据查询缓存

    的情况进行递增

    查询缓存命中率的计算公式是:Qcache_hits/(Qcache_hits + Com_select)。

    mysql> show status like '%Com_select%';

    +---------------+-------+

    | Variable_name | Value |

    +---------------+-------+

    | Com_select    | 1     |

    +---------------+-------+

    1 row in set (0.00 sec)

     

    mysql> show status like '%Qcache%';

    +-------------------------+---------+

    | Variable_name           | Value   |

    +-------------------------+---------+

    | Qcache_free_blocks      | 1       |

    | Qcache_free_memory      | 9418152 |

    | Qcache_hits             | 3       |

    | Qcache_inserts          | 9       |

    | Qcache_lowmem_prunes    | 0       |

    | Qcache_not_cached       | 10      |

    | Qcache_queries_in_cache | 9       |

    | Qcache_total_blocks     | 21      |

    +-------------------------+---------+

    8 rows in set (0.00 sec)

    此时的查询缓存命中率:3/(3+1)=75%;由于个人的测试数据库,查询较少,更行更少,命中率颇高。嘿嘿~~

    MySQL 提供了一系列的 Global Status 来记录 Query Cache 的当前状态,具体如下:

    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 数量

     

    分析和调整查询缓存的一个图示

    通用查询缓存优化方案

    使用多个较小的表,而不是用一个大表,对查询缓存有帮助。这种设计方式使失效策略工作在一个较好的颗粒度上。但是不要让这个想法过度影响架构设计,因为其他的因素能轻易抵消它的好处。

     成批地进行写入操作,而不是逐个执行,会有效率得多。因为这种方法只会引起一次失效操作。

     我们已经注意到在让缓存失效或清理一个大型缓存的时候,服务器可能会挂起相当长时间。至少在MySQL5.1之前的版本中是这样。一个容易的解决办法就是不要让query_cache_size 太大,256MB 已经太大了。

     不能在数据库或表的基础上控制查询缓存,但是可以使用SQL_CACHE 和SQL_NO_CACHE 决定是否缓存查询。也可以基于某个连接来运行或禁止缓存,可以通过用适当的值设定query_cache_size 来开启或关闭对某个连接的缓存。

    对于很多写入任务的应用程序,关闭查询缓存也许能改进性能。这样做可以消除缓存那些很快就会失效的查询所带来的开销。要记住在禁用的时候需要把query_cache_size 设置到0,这样就不会消耗任何内存。

    如果想让大多数查询都不使用缓存,但是有少部分查询能从缓存中极大地受益,这时可以将全局变量query_cache_type 设置为DEMAND,然后在想使用缓存的查询后面添加SQL_CACHE。尽管这会造成更多的工作,但是可以细粒度地控制缓存。相应地,如果想缓存大部分查询,只排除其中一小部分,就可以使用SQL_NO_CACHE

  • 相关阅读:
    5.19 省选模拟赛 T1 小B的棋盘 双指针 性质
    5.15 省选模拟赛 容斥 生成函数 dp
    5.15 省选模拟赛 T1 点分治 FFT
    5.15 牛客挑战赛40 B 小V的序列 关于随机均摊分析 二进制
    luogu P4929 【模板】舞蹈链 DLX
    CF 878E Numbers on the blackboard 并查集 离线 贪心
    5.10 省选模拟赛 拍卖 博弈 dp
    5.12 省选模拟赛 T2 贪心 dp 搜索 差分
    5.10 省选模拟赛 tree 树形dp 逆元
    luogu P6088 [JSOI2015]字符串树 可持久化trie 线段树合并 树链剖分 trie树
  • 原文地址:https://www.cnblogs.com/liqiu/p/2720762.html
Copyright © 2011-2022 走看看