Documentation Home
MySQL 8.0 参考手册  / 第8章优化  / 8.10 缓冲和缓存  / 8.10.3 The MySQL Query Cache  /  8.10.3.1 查询缓存如何运行

8.10.3.1 查询缓存如何运行

本节介绍查询缓存在运行时如何工作。第 8.10.3.3 节,“查询缓存配置”,描述了如何控制它是否运行。

传入的查询在解析之前与查询缓存中的查询进行比较,因此查询缓存认为以下两个查询不同:

SELECT * FROM tbl_name
Select * from tbl_name

查询必须完全相同(字节对字节)才能被视为相同。此外,由于其他原因,相同的查询字符串可能会被视为不同的。使用不同数据库、不同协议版本或不同默认字符集的查询被视为不同的查询并分别缓存。

缓存不用于以下类型的查询:

  • 作为外部查询的子查询的查询

  • 在存储函数、触发器或事件的主体内执行的查询

在从查询缓存中获取查询结果之前,MySQL 会检查用户是否对 SELECT涉及的所有数据库和表具有权限。如果不是这种情况,则不使用缓存的结果。

如果从查询缓存返回查询结果,则服务器会递增Qcache_hits 状态变量,而不是Com_select. 请参阅 第 8.10.3.4 节,“查询缓存状态和维护”

如果表发生更改,所有使用该表的缓存查询都会失效并从缓存中删除。这包括使用MERGE映射到已更改表的表的查询。可以通过多种类型的语句更改表,例如INSERTUPDATEDELETETRUNCATE TABLEALTER TABLEDROP TABLEDROP DATABASE

InnoDB使用表 时,查询缓存也在事务中工作 。

视图查询的结果SELECT被缓存。

查询缓存用于查询并存储由后续查询 SELECT SQL_CALC_FOUND_ROWS ...返回的值。即使前面的查询是从缓存中获取的,也会返回正确的值,因为找到的行数也存储在缓存中。查询本身不能被缓存 。SELECT FOUND_ROWS()FOUND_ROWS()SELECT FOUND_ROWS()

使用二进制协议使用mysql_stmt_prepare()and 发出的准备好的语句mysql_stmt_execute()(请参阅 C API 准备语句接口)受缓存限制。与查询缓存中语句的比较是基于?参数标记扩展后的语句文本。该语句仅与使用二进制协议执行的其他缓存语句进行比较。也就是说,出于查询缓存的目的,使用二进制协议发出的准备好的语句与使用文本协议发出的准备好的语句不同(请参阅 第 13.5 节,“准备好的语句”)。

如果查询使用以下任何函数,则无法缓存该查询:

在这些情况下也不会缓存查询:

  • 它指的是可加载函数或存储函数。

  • 它是指用户变量或本地存储的程序变量。

  • 它引用 、 或 数据库中mysqlINFORMATION_SCHEMAperformance_schema

  • 它指的是任何分区表。

  • 它是以下任何一种形式:

    SELECT ... LOCK IN SHARE MODE
    SELECT ... FOR UPDATE
    SELECT ... INTO OUTFILE ...
    SELECT ... INTO DUMPFILE ...
    SELECT * FROM ... WHERE autoincrement_col IS NULL

    最后一个表单未缓存,因为它用作获取最后一个插入 ID 值的 ODBC 解决方法。请参阅第 23 章连接器和 API的连接器/ODBC 部分 。

    使用隔离级别的事务中的语句 SERIALIZABLE也不能被缓存,因为它们使用LOCK IN SHARE MODE锁定。

  • 它使用TEMPORARY表格。

  • 它不使用任何表。

  • 它会生成警告。

  • 用户对任何涉及的表都具有列级权限。