查询缓存在本地设置上,但从不在服务器上?

时间:2012-12-03 21:47:13

标签: mysql caching percona

我在项目上遇到很多关于查询缓存的麻烦:我正在运行Percona的MySQL版本,在我的本地开发机器上和生产服务器上运行相同的版本。现在,启用查询缓存可以在我的本地计算机上获得出色的结果:几乎所有应该缓存的查询都是有效的。

现在,生产服务器上没有缓存完全相同的查询。一切都完全一样; mysql变量,数据库内容,代码库,登录用户,但是在生产过程中,只有少数查询被缓存,最重要的查询都被跳过。我无法弄清楚原因: - )

因此,寻找解决方案,我正在使用以下查询,用于从主题表中选择最新的3个主题:(这是最“重”的查询,是我绝对想要缓存的! )

SELECT `topic`.* FROM `topics` AS `topic` 
LEFT OUTER  JOIN `topics` AS `topic_helper` 
 ON (`topic`.`id` = `topic_helper`.`id` 
      AND `topic_helper`.`created_on` < `topic`.`created_on`) 
GROUP BY `topic`.`id` HAVING COUNT(*) < 3 
ORDER BY `topic`.`created_on` DESC;

所以,首先,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             | 10485760 |
| query_cache_strip_comments   | OFF      |
| query_cache_type             | ON       |
| query_cache_wlock_invalidate | OFF      |
+------------------------------+----------+

运行上述查询会在第一次运行后在本地缓存,因为SHOW PROFILE清楚地告诉我接近它的跟踪结束:

| Waiting for query cache lock   | 0.000001 |
| Waiting on query cache mutex   | 0.000001 |
| freeing items                  | 0.000000 |
| storing result in query cache  | 0.000002 |
| logging slow query             | 0.000001 |
| cleaning up                    | 0.000006 |
+--------------------------------+----------+

第二次调用会按预期从缓存中返回查询。

在生产服务器上,运行此查询永远不会将其存储在缓存中。 结果集完全相同,并且显然没有使用任何会使查询缓存无效的语句(根据http://dev.mysql.com/doc/refman/5.1/en/query-cache-operation.html的手册 - 我确信上述查询符合要求缓存它。)

为了完整起见,生产服务器上同一查询的SHOW PROFILE的完整输出将粘贴在此处:http://pastebin.com/7Jm5rmVd

另外,值得注意的是,尽管两台服务器上的配置完全相同,但我的本地版本为5.5.27,略高于生产5.5.17-55的版本。难道这就是问题..?

我将本地服务器的完整SHOW VARIABLES;输出作为生产服务器进行比较,以查看是否有任何缺失,但除了系统时区和日志文件的路径等之外没有任何区别。

那么,你们中间是否有人知道下一步该去哪儿?或者有什么可能导致这种情况的线索?

1 个答案:

答案 0 :(得分:1)

我们在这里使用Percona服务器,也使用社区MySQL。

查询缓存功能强大 - 而且非常复杂。 MySQL可以做的更糟糕的事情是返回一些陈旧的缓存数据。

MySQL不仅缓存查询,还缓存数据库数据 - 并使用索引来提高性能。

任何可能使查询缓存无效的内容都会使其无效。

根据经验,我们不太关注它是否被缓存......我们相信MySQL会智能地行动 - 如果出于任何原因它认为某些东西不应被缓存,它不会缓存它。我们做了什么 - 确保我们的查询尽可能高效和简单。

如果我可以这样说 - 我认为如果您的示例查询是“您最常用的”之一,那么无论查询缓存如何,您都会遇到严重的可伸缩性问题。一旦服务器忙碌,它就会像没有腿的狗一样跑!

根据您的pastebin条目 - 您至少创建了一个临时表,可能是由于外连接(或GROUP BY)。

我完全正常化 - 但有时性能需要另一条路线。

你能不能在某种查找/汇总表中自己缓存一些数据?触发器可以是你的朋友:)