mysql 开发进阶篇系列 17 MySQL Server(key_buffer与table_cache)
一.key_buffer
上一篇了解key_buffer设置,key_buffer_size指定了索引缓冲区的大小,它决定索引处理的速度,尤其是索引读的速度。通过检查状态值Key_read_requests和Key_reads,可以知道key_buffer_size设置是否合理。比例key_reads /key_read_requests应该尽可能的低,至少是1:100,1:1000更好(理解为key_reads物理IO次数越少越好)。
-- 一共有Key_read_requests个索引请求,一共发生了Key_reads次物理IO SHOW GLOBAL STATUS LIKE '%key_read%';
-- Key_reads/Key_read_requests ≈ 0.1%以下比较好 SELECT 693206.0/94745304.0
key_buffer_size只对MyISAM表起作用。即使你不使用MyISAM表,但是内部的临时磁盘表是MyISAM表,也要使用该值,可以使用检查状态值created_tmp_disk_tables得知详情。
SHOW GLOBAL STATUS LIKE '%created_tmp_disk_tables%';
总结建议:
对于1G内存的机器,如果不使用MyISAM表,推荐值是16M(8-64M)。
单个key_buffer的大小不能超过4G。
建议key_buffer设置为物理内存的1/4(针对MyISAM引擎),在很多情况下数据要比索引大得多。
如果机器性能优越,可以设置多个key_buffer,分别让不同的key_buffer来缓存专门的索引。
Key_reads/Key_read_requests的大小正常情况下得小于0.01。
二. table_cache (table_open_cache)
上面讲了索引缓存,这里讲表缓存 table_cache,在mysql 5.1之后叫做"table_open_cache"。这个参数表示数据库用户打开表的缓存数量(最大限制数),用于设置table高速缓存的数量。由于每个客户端连接都会至少访问一个表,因此此参数的值与max_connections有关。例如 对于200个并行运行的连接,应该让表的缓存至少有200 * N。这里N是可以执行的查询的一个连接中表的最大数量(表数量)。
表缓存机制是:当某一连接访问一个表时,MySQL会检查当前已缓存表的数量。如果该表已经在缓存中打开,则会直接访问缓存中的表已加快查询速度;如果该表未被缓存,则会将当前的表添加进缓存并进行查询。
在执行缓存操作之前,table_cache用于限制缓存表的最大数目:如果当前已经缓存的表未达到table_cache,则会将新表添加进来;若已经达到此值,MySQL将根据缓存表的最后查询时间、查询率等规则释放之前的缓存(释放机制与sqlserver一样)。
-- 表缓存限制数(默认是2000次) SHOW VARIABLES LIKE 'table_open_cache';
-- 最大并发连接数 SHOW VARIABLES LIKE 'max_connections';
可以通过检查mysqld的状态变量open_tables和opened_tables确定table_cache参数是否过小。 open_tables表示当前打开的表缓存数,如果执行flush tables操作,则系统会关闭一些当前没有使用的表缓存,而使得些状态值减小。opened_tables表示曾经打开的表缓存数(历史的),会一直进行累加。执行flush tables值不会减少。
-- 当前打开的表缓存数 SHOW GLOBAL STATUS LIKE 'open_tables';
-- 曾经打开的表缓存数 SHOW GLOBAL STATUS LIKE 'opened_tables';
2.1演示下open_tables和opened_tables值的变化(在另一台mysql上进行)
第一步:
-- 清空表缓存 FLUSH TABLES; -- 查看值为1(代表当前连接) SHOW GLOBAL STATUS LIKE 'open_tables';
-- 历史值为111 SHOW GLOBAL STATUS LIKE 'opened_tables';
第二步:
-- 执行一个查询 SELECT COUNT(1) FROM User1 -- 再次查询当前缓存数 SHOW GLOBAL STATUS LIKE 'open_tables';
--历史值也累加到113 SHOW GLOBAL STATUS LIKE 'opened_tables';
第三步:
-- 再执行一个相同查询, 会发现值没有增加,因为读的是缓存。 SELECT COUNT(1) FROM User1 SHOW GLOBAL STATUS LIKE 'open_tables';
SHOW GLOBAL STATUS LIKE 'opened_tables';
三. 修改table_cache值
下面来尝试修改table_cache值, 还是一样找到my.cnf
[root@xuegod64 etc]# vim my.cnf
[root@xuegod64 ~]# systemctl stop mysqld.service
[root@xuegod64 ~]# /bin/systemctl start mysqld.service
-- 服务停止重启后再次查看表缓存限制数。 SHOW VARIABLES LIKE 'table_open_cache';
四.table_cache总结
open_tables是当前表缓存数,类似于sql server的逻辑查询而非物理查询。 该open_tables的值对设置table_cache值有重要的参考价值。
如果Open_tables的值已经接近table_cache的值,且Opened_tables还在不断变大,则说明mysql正在将缓存的表释放以容纳新的表,此时可能需要加大table_cache的值。下面这台mysql服务器正是这种情况,1990接近最大限制2000,且历史值还在不断变大。 如下图:
比较适合的值建议:
Open_tables / Opened_tables >= 0.85
当前mysql的值:SELECT 1990.0/3286078.0=0.00061
Open_tables / table_cache <= 0.95
当前mysql的值:1990.0/2000.0=0.99500
下一篇: 你瞧,这妈爸可醉人了
推荐阅读
-
mysql 开发进阶篇系列 43 逻辑备份与恢复(基于时间和位置的不完全恢复)
-
mysql 开发进阶篇系列 42 逻辑备份与恢复
-
mysql 开发进阶篇系列 20 MySQL Server(innodb_lock_wait_timeout,innodb_support_xa,innodb _log_*)
-
mysql 开发进阶篇系列 48 xtrabackup (增量备份与恢复)
-
mysql 开发进阶篇系列 7 锁问题 (lock in share mode与for update)演示
-
mysql 开发进阶篇系列 52 权限与安全(系统四个权限表的粒度控制关系)
-
mysql 开发进阶篇系列 31 工具篇(mysql连接工具与MyISAM表压缩工具)
-
mysql 开发进阶篇系列 16 MySQL Server(myisam key_buffer)
-
mysql 开发进阶篇系列 17 MySQL Server(key_buffer与table_cache)
-
mysql 开发进阶篇系列 53 权限与安全(账号管理的各种权限操作 上)