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) 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相区别,不要混淆,后者才是清除查询缓存区中的所有的内容。 二、mysql事务 表的类型 :type = innodb活engine = innodb 1、开启事务 START TRANSACTION 或 BEGIN 2、提交事务(关闭事务) COMMIT 3、放弃事务(关闭事务) ROLLBACK 下列命令自动的结束一个事务(就好像你在执行这个命令之前做了一个 COMMIT): ALTER TABLE, BEGIN , CREATE INDEX , DROP DATABASE, DROP TABLE, RENAME TABLE , TRUNCATE, 4、折返点 SAVEPOINT adqoo_1 ROLLBACK TO SAVEPOINT adqoo_1 发生在折返点 adqoo_1 之前的事务被提交,之后的被忽略 5、事务的终止 设置“自动提交”模式 SET AUTOCOMMIT = 0 每条SQL都是同一个事务的不同命令,之间由 COMMIT 或 ROLLBACK隔开 掉线后,没有 COMMIT 的事务都被放弃 6、事务锁定模式 系统默认:不需要等待某事务结束,可直接查询到结果,但不能再进行修改、删除 缺点:查询到的结果,可能是已经过期的。 优点:不需要等待某事务结束,可直接查询到结果。 需要用以下模式来设定锁定模式 6-1、SELECT …… LOCK IN SHARE MODE(共享锁) 查询到的数据,就是数据库在这一时刻的数据(其他已commit事务的结果,已经反 应到这里了) SELECT 必须等待,某个事务结束后才能执行 6-2、SELECT …… FOR UPDATE(排它锁) 例如 SELECT * FROM tablename WHERE id<200 那么id<200的数据,被查询到的数据,都将不能再进行修改、删除、SELECT …… LOCK IN SHARE MODE操作 一直到此事务结束 共享锁 和 排它锁 的区别:在于是否阻断其他客户发出的 SELECT …… LOCK IN SHARE MODE命令 6-3、INSERT / UPDATE / DELETE 所有关联数据都会被锁定,加上排它锁 6-4、防插入锁 例如 SELECT * FROM tablename WHERE id>200 那么id>200的记录无法被插入 5、死锁 自动识别死锁 先进来的进程被执行,后来的进程收到出错消息,并按ROLLBACK方式回滚 innodb_lock_wait_timeout = n 来设置最长等待时间,默认是50秒 7、事务隔离模式 SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE 7-1、不带SESSION、GLOBAL的SET命令 只对下一个事务有效 7-2、SET SESSION 为当前会话设置隔离模式 7-3、SET GLOBAL 为以后新建的所有MYSQL连接设置隔离模式(当前连接不包括在内) 8、隔离模式 READ UNCOMMITTED 不隔离SELECT 其他事务未完成的修改(未COMMIT),其结果也考虑在内 READ COMMITTED 把其他事务的 COMMIT 修改考虑在内 同一个事务中,同一 SELECT 可能返回不同结果 REPEATABLE READ(默认) 不把其他事务的修改考虑在内,无论其他事务是否用COMMIT命令提交过同一个事务中,同一 SELECT 返回同一结果(前提是本事务,不修改) SERIALIZABLE 和REPEATABLE READ类似,给所有的SELECT都加上了 共享锁 出错处理 根据出错信息,执行相应的处理 InnoDB和MyISAM是在使用MySQL最常用的两个表类型,各有优缺点,视具体应用而定。下面是已知的两者之间的差别,仅供参考。 1.InnoDB不支持FULLTEXT类型的索引。 2.InnoDB 中不保存表的具体行数,也就是说,执行select count(*) from table时,InnoDB要扫描一遍整个表来计算有多少行,但是MyISAM只要简单的读出保存好的行数即可。注意的是,当count(*)语句包含 where条件时,两种表的操作是一样的。 3.对于AUTO_INCREMENT类型的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中,可以和其他字段一起建立联合索引。 4.DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除。 5.LOAD TABLE FROM MASTER操作对InnoDB是不起作用的,解决方法是首先把InnoDB表改成 MyISAM表,导入数据后再改成InnoDB表,但是对于使用的额外的InnoDB特性(例如外键)的.表不适用。 另外,InnoDB表的行锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范.围,InnoDB表同样会锁全表,例如update table set num=1 where name like “%aaa%” 任何一种表都不是万能的,只用恰当的针对业务类型来选择合适的表类型,才能最大的发挥MySQL的性能优势。 6、innoDB支持事务,MyISAM不支持事务,MyISAM:不支持事务,用于只读程序提高性能 InnoDB:支持ACID事务、行级锁、并发
|