数据库

位置:IT落伍者 >> 数据库 >> 浏览文章

MySQL 查询缓存


发布日期:2023年04月04日
 
MySQL 查询缓存
从 MySQL 开始MySQL server 有一个重要的特征Query Cache 当在使用中查询缓存会存储一个 SELECT 查询的文本与被传送到客户端的相应结果如果之后接收到一个同样的查询服务器将从查询缓存中检索结果而不是再次分析和执行这个同样的查询

注意查询缓存绝不返回过期数据当数据被修改后在查询缓存中的任何相关词条均被转储清除

在某些表并不经常更改而你又对它执行大量的相同查询时查询缓存将是非常有用的对于许多 WEB 服务器使用大量的动态信息这是一个很典型的情况

下面是查询缓存的一个性能数据(这些结果的产生是通过在一个 a Linux Alpha x MHzGB RAM 和 MB 查询缓存上执行 MySQL 基准套件和到的)

如果你执行的所有查询均是简单的(比如从表中一行一行的选取)但是仍然是不同的所以该查询不能被缓沖查询缓存处于活动时开销为 %这可以被看作是最差的情况然而在实际情况下查询是比我们的简单示例要复杂得多的所以开销通常显着得低

在只有一行记录表中搜索一行后搜索将快 % 这可以被认为是接近于对一个被缓沖的查询所期望的最小的加速

如果你希望禁用查询缓存设置 query_cache_size=禁用了查询缓存将没有明显的开销(在配置选项 withoutquerycache 的帮助下查询缓存可以被排除在外码之外)

查询缓存如何运作

查询在分析之前先被比较因而

SELECT * FROM tbl_name

Select * from tbl_name

对于查询缓存被当作是不同的查询因而查询需要严格的一致(字节对字节的)才会被认为是同样的 另外如果一个客户端使用一个新的连接协议格式或不同于其它客户端的另一个字符集一个查询将被视为不同的

使用不同数据库的使用不同协议版本的或使用不同的缺省字符串的查询将被认为是不同的查询并将分别的缓沖

高速缓沖不对 SELECT CALC_ROWS … 和 SELECT FOUND_ROWS() … 类型的查询起作用因为找到的行的数目也是被存储在缓沖里的

如果查询结果被从查询缓存中返回那么状态变量 Com_select 将不会被增加但是 Qcache_hits 却会增加

查看章节 查询缓存的状态和维护

如果一个表发生的改变 (INSERT UPDATE DELETE TRUNCATE ALTER 或 DROP TABLE|DATABASE)那么所有这张表使用的缓沖的查询(可能通过一个 MRG_MyISAM 表!)将被得失效并从缓沖中移除

InnoDB 表的事务所做的更改将在一个 COMMIT 被完成时使数据失效

如果一个查询包括下面的函数它将不能被缓沖

函数 函数 函数

UserDefined Functions CONNECTION_ID FOUND_ROWS

GET_LOCK RELEASE_LOCK LOAD_FILE

MASTER_POS_WAIT NOW SYSDATE

CURRENT_TIMESTAMP CURDATE CURRENT_DATE

CURTIME CURRENT_TIME DATABASE

ENCRYPT (只有一个参数调用) LAST_INSERT_ID RAND

UNIX_TIMESTAMP (无参数调用) USER BENCHMARK

如果一个查询包含用户变量引用 MySQL 系统数据库或下列之一的格式SELECT … IN SHARE MODE SELECT … INTO OUTFILE … SELECT … INTO DUMPFILE … 或 SELECT * FROM AUTOINCREMENT_FIELD IS NULL (检索最后一个插入 ID ODBC 语句)该查询亦不可以被缓存

然而FOUND ROWS() 将返回正确的值即使先前的查询是从缓存中读取的

万一一个查询不使用任何表或使用临时表或用户对任何相关表有一个列权限那么查询将不会被缓存

在一个查询从查询缓存中读取前MySQL 将检查用户对所有相关的数据库和表有 SELECT 权限如果不是这种情况缓存的结果将不能被使用

查询缓存设置

查询缓存为了 mysqld 添加了几个 MySQL 系统变量它可以在配置文件中被设置或在启动 mysqld 时的命令行上设置

query_cache_limit 不缓存大于这个值的结果(缺省为 M)

query_cache_min_res_unit 这个变量从 被引进 查询的结果 (已被传送到客户端的数据) 在结果检索期间被存储到查询缓存中因而数据不会以一个大块地处理查询缓存在需要时分配块用于处理这个数据所以当一个块被填充后一个新的块被分配甚为内存分配操作是昂贵的查询缓存以最小的尺寸 query_cache_min_res_unit 分配块当一个查询执行完成最后的结果块被修整到实际数据的尺寸大小以便未使用的内存被释放

query_cache_min_res_unit 的缺省值为 KB在大多数据情况下已够用了

如果你有许多查询返回一个较小的结果缺省的块尺寸可能会引起内存碎片 (显示为一个很大数量的空闲块(Qcache_free_blocks)这将引起查询缓存不得不因缺乏内存(Qcache_lowmem_prunes)而从缓存中删除查询)在这种情况下你应该减少 query_cache_min_res_unit

如果你的主要查询返回的是大的结果集(查看 Qcache_total_blocks 和 Qcache_queries_in_cache)你可以通过增加 query_cache_min_res_unit 来增加性能然而要小心不要将它设得太大

query_cache_size 为了存储老的查询结果而分配的内存数量 (以字节指定) 如果设置它为 查询缓沖将被禁止(缺省值为

query_cache_type 这个可以被设置为 (只能是数字) 选项 含义

(OFF 不缓存或重新得到结果)

(ON 缓存所有的结果除了 SELECT SQL_NO_CACHE … 查询)

(DEMAND 仅缓存 SELECT SQL_CACHE … 查询)

在一个线程(连接)内查询缓存的行为可以被改变句法如下所示

QUERY_CACHE_TYPE = OFF | ON | DEMAND QUERY_CACHE_TYPE = | |

选项 含义

or OFF 不缓存或重新得到结果

or ON 缓存所有的结果除了 SELECT SQL_NO_CACHE … 查询

or DEMAND 仅缓存 SELECT SQL_CACHE … 查询

在 SELECT 中的查询缓存选项

有两个可能的查询缓存相关的参数可以在一个 SELECT 查询中被指定

选项 含义

SQL_CACHE 如果 QUERY_CACHE_TYPE 为 DEMAND允许该查询被缓存如果 QUERY_CACHE_TYPE 为 ON这是缺省的如果 QUERY_CACHE_TYPE 为 OFF它不做任何事

SQL_NO_CACHE 使这个查询不被缓存不允许这个查询被存储到高速缓存中

查询缓存的状态和维护

使用 FLUSH QUERY CACHE 命令你可以整理查询缓存以更好的利用它的内存这个命令不会从缓存中移除任何查询FLUSH TABLES 会转储清除查询缓存

RESET QUERY CACHE 使命从查询缓存中移除所有的查询结果

你可以检查查询缓存在你的 MySQL 是否被引进

mysql> SHOW VARIABLES LIKE have_query_cache;

+++

| Variable_name | Value |

+++

| have_query_cache | YES |

+++

row in set ( sec)

在 SHOW STATUS 中你可以监视查询缓存的性能

变量 含义

Qcache_queries_in_cache 在缓存中已注册的查询数目

Qcache_inserts 被加入到缓存中的查询数目

Qcache_hits 缓存采样数数目

Qcache_lowmem_prunes 因为缺少内存而被从缓存中删除的查询数目

Qcache_not_cached 没有被缓存的查询数目 (不能被缓存的或由于 QUERY_CACHE_TYPE)

Qcache_free_memory 查询缓存的空闲内存总数

Qcache_free_blocks 查询缓存中的空闲内存块的数目

Qcache_total_blocks 查询缓存中的块的总数目

Total number of queries = Qcache_inserts + Qcache_hits + Qcache_not_cached

查询缓存使用变长的块因而 Qcache_total_blocks 和 Qcache_free_blocks 可能显示查询缓存的碎片在 FLUSH QUERY CACHE 之后只有剩余一个单独的(大的)空闲块

注意每个查询最小需要两个块(一个用于存储查询文本另一个或多个用于存储查询结果)同样的每个被一个查询使用的表需要一个块但是如果有两个或更多的查询使用同一张表仅仅只需要分配一个块就行了

你可以使用状态变量 Qcache_lowmem_prunes 来谐调查询缓存尺寸它计数被从缓存中移除的查询该查询的移除是为了释放内存以缓存新建的查询查询缓存使用一个 least recently used (LRU) 策略来判断从缓存中移除哪个查询

上一篇:MYSQL死锁相关查找

下一篇:sql2005安装图解