MySQL 查询缓存
查询缓存是用来缓存一个查询SQL的结果集,下次执行相同SQL时,直接从查询缓存里取得已有的结果,而不需要重新对SQL解析,优化,执行。
查询缓存是会话间共享的,即不同会话执行相同的SQL,都可以从查询缓存中直接取得结果。
相同的SQL,意味着谓词条件以及大小写都要严格一致。
在使用查询缓存之前,MySQL依然会检查用户对查询对象的权限,没有权限则无法使用查询缓存。
每次使用查询缓存,会使状态变量qcache_hits加1,但com_select不变。
控制查询缓存的参数
1.have_query_cache,查询缓存功能是否可用
mysql> SHOW VARIABLES LIKE ‘have_query_cache’;
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| have_query_cache | YES |
+------------------+-------+
- query_cache_size,单位bytes,查询缓存大小,设为0表示关闭查询缓存,必须是1024的倍数,查询缓存至少需要40KB。
- query_cache_type,查询缓存类型,取值为0|off,1|on,2|demand,1时缓存所有查询,2时只有在select sql_cache时才缓存查询
开启查询缓存
配置query_cache_size大于0和query_cache_type不为0|off时,即开启查询缓存。
关闭查询缓存
query_cache_size=0或query_cache_type=0|off
查询缓存不生效的情况
在以下情况下,即使SQL严格一致,也不会缓存查询:
1.子查询
2.函数、触发器、事件里的SQL
当SQL使用了以下这些函数,将不会进行查询缓存
• AES_DECRYPT()
• AES_ENCRYPT()
• BENCHMARK()
• CONNECTION_ID()
• CONVERT_TZ()
• CURDATE()
• CURRENT_DATE()
• CURRENT_TIME()
• CURRENT_TIMESTAMP()
• CURRENT_USER()
• CURTIME()
• DATABASE()
• ENCRYPT() with one parameter
• FOUND_ROWS()
• GET_LOCK()
• IS_FREE_LOCK()
• IS_USED_LOCK()
• LAST_INSERT_ID()
• LOAD_FILE()
• MASTER_POS_WAIT()
• NOW()
• PASSWORD()
• RAND()
• RANDOM_BYTES()
• RELEASEALLLOCKS()
• RELEASE_LOCK()
• SLEEP()• SYSDATE()
• UNIX_TIMESTAMP() with no parameters
• USER()
• UUID()
• UUID_SHORT()
对于SQL出现以下情况,也不会进行查询缓存
1.使用了用户自定义的函数;
2.使用了用户自定义变量或者其他程序里的本地变量;
3.SQL同时查询了mysql, INFORMATION_SCHEMA,performance_schema三个数据库中的一个或多个;
4.查询了分区表;
5.使用了以下这些语法:
SELECT ... LOCK IN SHARE MODE
SELECT ... FOR UPDATE
SELECT ... INTO OUTFILE ...
SELECT ... INTO DUMPFILE ...
SELECT * FROM ... WHERE autoincrement_col IS NULL
6.使用了临时表;
7.没有查询任何表;
8.产生warnings;
9.只拥有查询表的部分列权限。
查询缓存会失效
一旦一个表发生了数据变更,该表对应的查询缓存就会失效,在执行相同SQL时需要重新维护查询缓存,所以对于变更频繁的数据库,查询缓存的作用几乎为零。会使查询缓存失效的操作例如有:
INSERT, UPDATE, DELETE, TRUNCATE TABLE, ALTER TABLE, DROP TABLE, DROP DATABASE
不建议开启查询缓存
由于表的更新会导致查询缓存失效,通常OLTP都是DML频繁的库,在这种情况下,维护查询缓存的代价高于查询缓存带来的好处,甚至查询缓存可能并不起任何作用,所以建议将查询缓存关闭。
在MySQL8.0里已经把查询缓存的功能删除了。
还没有评论,来说两句吧...