我在一个项目的查询缓存方面遇到了很多麻烦:我正在运行 MySQL 的 Percona 风格,在我的本地开发机器上和生产服务器上的版本相同。现在,启用查询缓存在我的本地机器上给了我很好的结果:几乎所有应该缓存的查询,实际上都是。
现在,生产服务器上没有缓存完全相同的查询。一切都一模一样;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;
输出与生产服务器进行了比较,以查看是否缺少任何内容,但除了系统时区和日志文件的路径等之外,没有什么不同。
那么,你们中的任何人都知道下一步该去哪里寻找吗?或者有任何线索可能导致这种情况?