mysql缓存如何使用

mysql缓存如何使用,第1张

我们都知道 MySQL 的 Table Cache 是表定义的缓存,江湖上流传着各种对这个参数的调优方法。

table cache 的作用,就是节约读取表结构文件的开销。对于table cache 是否命中,其实table cache 是针对于线程的,每个线程有自己的缓存,只缓存本线程的表结构定义。不过我们发现,strace 中没有关于表结构文件的 open *** 作(只有 stat *** 作,定位表结构文件是否存在),也就是说 table cache 不命中,不一定需要读取表结构文件。这种感觉好像是:在不命中 table cache 时,命中了另外一个表结构缓存。

运维建议:

我们读一下 MySQL 的文档,关于 table_open_cache 的建议值公式:建议值 = 最大并发数 * join 语句涉及的表的最大个数。

通过实验我们容易理解:table_cache 是针对于线程的,所以需要最大并发数个缓存。另外,一个语句 join 涉及的表,需要同时在缓存中存在。所以最小的缓存大小,等于语句 join 涉及的表的最大个数。将这两个数相乘,就得到了 MySQL 的建议值公式。

当在使用中,查询缓存会存储一个 SELECT 查询的文本与被传送到客户端的相应结果。如果之后接收到一个同样的查询,服务器将从查询缓存中检索结果,而不是再次分析和执行这个同样的查询。

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

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

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

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

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

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

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

SELECT * FROM tbl_name和Select * from tbl_name

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

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

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

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

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

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

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

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

函数 函数 函数

User-Defined 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 权限。

MySQL缓存机制简单的说就是缓存sql文本及查询结果,如果运行相同的sql,服务器直接从缓存中取到结果,而不需要再去解析和执行sql。如果表更改 了,那么使用这个表的所有缓冲查询将不再有效,查询缓存值的相关条目被清空。更改指的是表中任何数据或是结构的改变,包括INSERT、UPDATE、 DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE等,也包括那些映射到改变了的表的使用MERGE表的查询。显然,这对于频繁更新的表,查询缓存是不适合的,而对于一些不常改变数据且有 大量相同sql查询的表,查询缓存会节约很大的性能。命中条件

缓存存在一个hash表中,通过查询SQL,查询数据库,客户端协议等作为key.在判断是否命中前,MySQL不会解析SQL,而是直接使用SQL去查询缓存,SQL任何字符上的不同,如空格,注释,都会导致缓存不命中.

如果查询中有不确定数据,例如CURRENT_DATE()和NOW()函数,那么查询完毕后则不会被缓存.所以,包含不确定数据的查询是肯定不会找到可用缓存的


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/7344382.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-04
下一篇 2023-04-04

发表评论

登录后才能评论

评论列表(0条)

保存