7

我正在调整一个大型查询,并希望在之前和之后从相同的基线运行它,以进行比较。

我知道 mysql 查询缓存,但它与我无关,因为这 2 个查询无论如何都不会被缓存。

正在缓存的是缓冲池中的 innodb 页面。有没有办法清除整个缓冲池,以便我可以从同一起点比较两个查询?

虽然在运行每个查询后重新启动 mysql 服务器无疑会起作用,但如果可能的话,我想避免这种情况

4

2 回答 2

13

警告:以下仅适用于 MySQL 5.5 和 MySQL 5.1.41+(InnoDB 插件)

使用以下设置调整 InnoDB 缓冲池中条目的持续时间:

// This is 0.25 seconds
SET GLOBAL innodb_old_blocks_time=250; 
SET GLOBAL innodb_old_blocks_pct=5;
SET GLOBAL innodb_max_dirty_pages_pct=0;

完成测试后,将它们设置回默认值:

SET GLOBAL innodb_old_blocks_time=0;
SET GLOBAL innodb_old_blocks_pct=37;
SET GLOBAL innodb_max_dirty_pages_pct=90;
// 75 for MySQL 5.5/MySQL 5.1 InnoDB Plugin

查看这些设置的定义

于 2012-05-10T22:25:24.860 回答
3

简单得多... 运行两次

SELECT SQL_NO_CACHE ...;

看看第二个时机。

第一个预热buffer_pool;第二个通过SQL_NO_CACHE. (在 MySQL 8.0 中,离开SQL_NO_CACHE; 它消失了。)

因此,第二个时间很好地表明了在具有热缓存的生产系统中需要多长时间。

此外,查看处理程序计数

FLUSH STATUS;
SELECT ...;
SHOW SESSION STATUS LIKE 'Handlers%';

给出了触摸多少行的相当清晰的图片。这反过来又让您对查询花费了多少精力有一个很好的感觉。请注意,这可以在小型数据集上非常成功(并且快速)地运行。然后,您可以(通常)外推到更大的数据集。

“Handler_read”可能正在读取索引行或数据行。它可能是“下一个”行(因此可能缓存在为前一行读取的块中),也可能是随机的(因此可能会受到另一个磁盘命中)。也就是说,该技术对“需要多少块”没有多大帮助。

这种 Handler 技术不受其他情况的影响;它给出了一致的结果。

“Handler_write”表示需要一个 tmp 表。

近似于表中行数(或这样的倍数)的数字可能表示表扫描。与 相同的数字LIMIT 可能意味着您构建了一个很好的索引,以至于它消耗了它LIMIT本身。

如果您确实刷新了 buffer_pool,您可以观察更改以给出在系统Innodb_buffer_pool_reads中读取的页面数的精确(?)计数。这将包括几乎总是被缓存的非叶索引页。如果系统中发生其他任何事情,则不应信任此值,因为它是“全局”的,而不是“会话”。STATUS

于 2016-05-01T21:33:09.823 回答