设为首页收藏本站

数码鹭岛论坛

 找回密码
 注-册

QQ登录

只需一步,快速开始

搜索
查看: 3075|回复: 0
打印 上一主题 下一主题

Mysql高级编程之查询缓存区的优化

[复制链接]
跳转到指定楼层
1#
发表于 2011-5-4 20:56:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
查询缓存区(query cache)是Mysql 4.0版本后引入的一项功能,本意是提高SQL查询性能,即把某些SQL查询命令的结果存放在内存里,当其他用户再次执行一条完全相同的查询命令 时,Mysql将会把缓存在内存里的查询结果直接发送给他,而不用再对数据库表进行查询。
但是并不是说查询缓存区就只有优点,而没有缺点,我举个例子,一个项目里如果是update, delete ,insert等数据库操作比select操作更多,那我想觉得这时候就不适合开启查询缓存区的功能,为什么呢,原因很简单,查询缓存区缓存的是查询的结 果,如果数据库表内容经常的改变,那很多查询结果多必须从查询缓存区里删除掉,特别是内存较小的系统,这样的话,只会加剧数据库的负担。

基于 这一点,用不用开启查询缓存区的功能,查阅不少文档后,总结几条如下:

1. 就是查询缓存区适合select 操作较多,而insert update delete操作较少的情况,并且重复的SQL查询越多,效果越好。

2. 就是SQL查询语句命令必须严格的相同,包括字母大小写,空格,在此强烈建议你使用视图查询。

3. 就是select 命令里不能含有一些特殊的函数,比如CUDATE(),NOW(),有这些函数在里面,查询缓存区几乎不起作用,只会给系统带来额外开销。

查 询缓存区的启用
如果 query_cache_size=0,那么当前没有开启查询缓存区
在my.cnf的 [mysqld]配置段
开启查询缓存区有几个相关项,如
query_cache_size =128M
query_cache_type = 1  (有三个值,分别是0,1,2)
qurey_cache_limit=128K;
意思是给启用查询缓存区并给查询缓存区分 配128M的内存空间, 而且允许查询的结果数据必须不大于128KB大小
query_cache_type为1,开启缓存,如果在SQL语句里加上了 SQL_NO_CACHE关键字的,强制不缓存查询结果。比如:

SELECT SQL_NO_CACHE field1, field2 FROM TABLE1

query_cache_type为0,表示关闭SQL语句里的SQL_CACHE和 SQL_NO_CACHE功能,也就是禁用查询缓存功能。
query_cache_type为2,表示在SQL语句里,只有包含着 SQL_CACHE的查询才会进入查询缓存区。比如:SELECT SQL_CALHE * FROM table

Mysql的查询缓存区的优化
查看查询缓存区的相关变量:

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             | 33554432 |
| query_cache_type             | ON       |
| query_cache_wlock_invalidate | OFF      |
+——————————+———-+
6 rows in set (0.00 sec)
(你可以将以上的变量定义到mysql的配置文件里,windows的是my.ini,如果部配置,则启用默认数值)

have_query_cache
是否支持查询缓存区 “YES”表是支持查询缓存区

query_cache_limit 可缓存的Select查询结果的最大值 1048576 byte /1024 = 1024kB 即最大可缓存的select查询结果必须小于1024KB

query_cache_min_res_unit 每次给query cache结果分配内存的大小 默认是 4096 byte 也即 4kB

在这里,我延伸三点重要的东西

1.当查询进行的时候,Mysql把查询结果保存在qurey cache中,但是有时候要保存的结果比较大,超过了query_cache_min_res_unit的值 ,这时候mysql将一边检索结果,一边进行慢慢保存结果,所以,有时候并不是
把所有结果全部得到后再进行一次性保存,而是每次分配一块query_cache_min_res_unit 大小的内存空间保存结果集,
使用完后,接着再分配一个这样的块,如果还不不够,接着再分配一个块,依此类推,也就是说,有可能在一次查询中,
mysql要进行多次内存分配的操作,而我们应该知道,频繁操作内存都是要耗费时间的。

2. 内存碎片的产生。当一块分配的内存没有完全使用时,MySQL会把这块内存Trim掉,把没有使用的那部分归还以重复利用。比如,第一次分配4KB,只用 了3KB,剩1KB,第二次连续操作,分配4KB,用了2KB,剩2KB,这两次连续操作共剩下的1KB+2KB=3KB,不足以做个一个内存单元分配, 这时候,内存碎片便产生了。

3.内存块的概念,先看下这个:

mysql> show status like ‘qcache%’;
+————————-+———-+
| Variable_name           | Value    |
+————————-+———-+
| Qcache_free_blocks      | 5096     |
| Qcache_free_memory      | 18964096 |
| Qcache_hits             | 12192192 |
| Qcache_inserts          | 3560370  |
| Qcache_lowmem_prunes    | 17326    |
| Qcache_not_cached       | 303599   |
| Qcache_queries_in_cache | 10201    |
| Qcache_total_blocks     | 25937    |
+————————-+———-+
8 rows in set (0.00 sec)

Qcache_total_blocks 表示所有的块

Qcache_free_blocks 表示未使用的块 这个值比较大,那意味着,内存碎片比较多,用flush query cache清理后,
为被使用的块其值应该为1或0 ,因为这时候所有的内存都做为一个连续的快在一起了:

mysql> show status like ‘qcache%’;
+————————-+———-+
| Variable_name           | Value    |
+————————-+———-+
| Qcache_free_blocks      | 1        |
| Qcache_free_memory      | 18539240 |
| Qcache_hits             | 12192502 |
| Qcache_inserts          | 3560515  |
| Qcache_lowmem_prunes    | 17326    |
| Qcache_not_cached       | 303607   |
| Qcache_queries_in_cache | 10318    |
| Qcache_total_blocks     | 21081    |
+————————-+———-+
8 rows in set (0.00 sec)

其他几个状态变量的意义:

Qcache_free_memory 表示查询缓存区现在还有多少的可用内存
Qcache_hits 表示查询缓存区的命中个数,也就是直接从查询缓存区作出响应处理的查询个数
Qcache_inserts 表示查询缓存区此前总过缓存过多少条查询命令的结果
Qcache_lowmem_prunes 表示查询缓存区已满而从其中溢出和删除的查询结果的个数
Qcache_not_cached 表示没有进入查询缓存区的查询命令个数
Qcache_queries_in_cache 查询缓存区当前缓存着多少条查询命令的结果

优化提示:
如果Qcache_lowmem_prunes 值比较大,表示查询缓存区大小设置太小,需要增大。
如果Qcache_free_blocks 较多,表示内存碎片较多,需要清理,flush query cache
根据我看的 《High Performance MySQL》中所述,关于query_cache_min_res_unit大小的调优
,书中给出了一个计算公式,可以供调优设置参考:
query_cache_min_res_unit = (query_cache_size – Qcache_free_memory) / Qcache_queries_in_cache

还要注意一点的是,FLUSH QUERY CACHE 命令可以用来整理查询缓存区的碎片,改善内存使用状况,
但不会清理查询缓存区的内容,这个要和RESET QUERY CACHE相区别,不要混淆,后者才是清除查询缓存区中
的所有的内容。

总结:

一般是是查询并设置query_cache_type,have_query_cache,query_cache_size,query_cache_limit四个选项
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享
您需要登录后才可以回帖 登录 | 注-册

本版积分规则

小黑屋|手机版|Archiver|数码鹭岛 ( 闽ICP备20006246号 )  

counter

GMT+8, 2025-12-4 00:17 , Processed in 0.073155 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表