如何禁用MySQL查询缓存

Sof*_*ory 28 mysql caching

我试图对不同列上的不同查询进行一些基准测试,但MySQL不会让我这样做.在第一次执行查询后,我再也无法获得该查询的相同执行时间.例如,如果查询在第一次执行0.062秒时,我永远无法获得第二次,第三次等运行的相同执行时间.它变为0秒或类似0.015的东西.

我已经阅读了很多关于禁用和清除MySQL查询缓存的帖子,但它们都没有对我有任何帮助.

喜欢这个SO帖子在这里

无论我做什么,MySQL似乎都坚持使用缓存结果.

我重新启动MySQL Workbench然后运行;

set global query_cache_type=0;
set global query_cache_size=0;
flush query cache;
reset query cache;
Run Code Online (Sandbox Code Playgroud)

执行时间持续显示0秒.

只有我无法更改的服务器变量是"have_query_cache".它的值为"是",当我尝试将其设置为"no"时,Workbench表示它是只读的.

我也这样做;

set profiling=1;
run my select query
show profile for query 2;
Run Code Online (Sandbox Code Playgroud)

分析结果显示:

'starting', '0.000077'
'checking permissions', '0.000007'
'Opening tables', '0.000016'
'init', '0.000035'
'System lock', '0.000009'
'optimizing', '0.000013'
'statistics', '0.000094'
'preparing', '0.000008'
'executing', '0.000002'
'Sending data', '0.000016'
'end', '0.000002'
'query end', '0.000003'
'closing tables', '0.000005'
'freeing items', '0.000139'
'cleaning up', '0.000009'
Run Code Online (Sandbox Code Playgroud)

如果我没有错,这表明没有使用缓存吗?但我仍然看到0秒.执行时间.

编辑:我正在运行的查询是使用"SQL_NO_CACHE"的SELECT查询,如下所示:

SELECT SQL_NO_CACHE col1,now() from mytable where col2="some_value"
Run Code Online (Sandbox Code Playgroud)

(我添加了now()函数来帮助我防止查询缓存)

Edit2:我使用的是innoDB,MySQL 5.6.10

有人可以帮助我,因为我看不到这里发生了什么.

非常感谢!

ESG*_*ESG 23

这可能是由于数据本身的缓存,而不是查询缓存.

要确保,可以通过在SELECT语句后添加SQL_NO_CACHE来禁用单个语句的查询缓存.

例如:

SELECT SQL_NO_CACHE field FROM table.

  • 清除缓冲池的唯一方法是重启MySQL实例. (3认同)

Qua*_*noi 10

首次运行查询会使InnoDB缓冲池填充表的相关块.

由于重新运行查询需要完全相同的块,因此在重新运行时,它会使查询无需从磁盘读取它们,从而大大加快了查询速度.

  • @sr但它会.磁盘很慢.从内存加载数据比从磁盘加载速度快得多. (3认同)

Bil*_*win 7

您可以验证缓冲池页面读取与必须转到磁盘以获取页面的页面读取之间的区别:

mysql> SHOW SESSION STATUS LIKE 'Innodb_buffer_pool_read%';
mysql> ...run a query...
mysql> SHOW SESSION STATUS LIKE 'Innodb_buffer_pool_read%';
Run Code Online (Sandbox Code Playgroud)

比较报告中的这些值,并注意它们增长了多少:

+---------------------------------------+----------+
| Variable_name                         | Value    |
+---------------------------------------+----------+
| Innodb_buffer_pool_read_requests      | 10327490 |
| Innodb_buffer_pool_reads              | 1133     |
+---------------------------------------+----------+
Run Code Online (Sandbox Code Playgroud)

read_requests是逻辑页读取,可以从网页已经在缓冲池读取.如果在查询后此数字增长,但读取不会增长,那么您的查询仅从缓冲池获得其结果.

读取是页面的读取数不得不出去到磁盘和承担的I/O成本页面复制到缓冲池.如果在查询后此数字增长,则必须从磁盘加载数据.

有关内存访问性能与磁盘访问性能之间差异的更多信息,请参阅http://everythingisdata.wordpress.com/2009/10/17/numbers-everyone-should-know/


你的评论:

"打开表"与InnoDB表的内存缓存有关,有点像数据字典.重新启动后第一次引用表时会打开表.内存数据字典中的给定表条目无限期地保留在内存中,因此如果您有数千个表,则内存使用量会变得非常大.在MySQL 5.6中,他们有一些新的调整变量来限制内存使用量,并逐出不常用的表.但是这整个机制与缓冲池是分开的,缓冲池存储数据和索引的页面.

"统计"也与缓冲池分开.InnoDB维护有关数据和索引的内存统计信息,用于指导查询优化器.首次访问InnoDB表,运行SHOW TABLE STATUS或对INFORMATION_SCHEMA运行某些查询时,运行ANALYZE TABLE时,以及表的大小发生显着变化时,统计信息会自动刷新.InnoDB生成这些统计信息,从表中随机读取固定数量的页面,如果你有一个冷缓冲池,这很可能会打到磁盘上.