【问题标题】:MySQL cache of subset queries子集查询的 MySQL 缓存
【发布时间】:2017-06-04 10:11:18
【问题描述】:

我正在尝试在可接受的时间内在大型数据库上运行查询。我正在考虑优化查询本身(例如Clarification of join order for creation of temporary tables),这使我从根本无法完成查询(有 20 小时上限)到完成它,但时间仍然不可接受。

在实验中,我发现了以下我想了解的奇怪行为:我想在 2 年的时间范围内进行查询。如果我尝试直接这样运行它,那么它仍然不会在我允许测试的 10 分钟内完成。如果我将它减少到该范围的前 6 个月,它将很快完成。如果我然后通过在范围内添加几个月来逐步重新运行查询(即运行 8 个月,然后运行 ​​10 个月,直到整整 2 年),每次连续尝试都将完成,我可以引导我的方式能够得到我想要的整整两年。

我怀疑这可能是由于 MySQL 服务器缓存了结果,但这似乎与文档不匹配:

如果稍后收到相同的语句,则服务器从查询缓存中检索结果,而不是再次解析和执行该语句。

http://dev.mysql.com/doc/refman/5.7/en/query-cache.html

那里的关键词似乎是“相同的”,并且查询相同的明显要求被我所做的其他阅读强化了。 (The docs 甚至表明查询上的比较是字面的,以至于用“SELECT”与“select”编写的逻辑等效查询将不匹配。)在我的情况下,每个后续查询都包含前一个查询的全部范围查询,但没有两个是相同的。

此外,表格会在一夜之间更新。因此,昨天结束时,我们在 19 秒内运行了完整的 2 年查询,大概是因为我们已经至少获得了一次完整结果,所以它被缓存了。今天我们不能再让查询运行了,这似乎与昨晚更新表时缓存已失效的情况一致。

所以问题是:在这种情况下是否有一些特殊情况允许服务器缓存?如果是,那记录在哪里?如果没有,还有什么其他会导致这种行为的建议?

【问题讨论】:

    标签: mysql database caching select query-cache


    【解决方案1】:

    是的,有一个缓存可以优化(一般)对硬盘的访问。它实际上是每个基于存储的数据库系统的一个非常重要的部分,因为从硬盘读取数据(或将临时数据写入)通常是大多数查询最相关的瓶颈。

    对于 InnoDB,这称为InnoDB Buffer Pool

    InnoDB 维护一个称为缓冲池的存储区域,用于在内存中缓存数据和索引。了解 InnoDB 缓冲池是如何工作的,并利用它来将频繁访问的数据保存在内存中,是 MySQL 调优的一个重要方面。有关 InnoDB 缓冲池如何工作的信息,请参阅 InnoDB 缓冲池 LRU 算法。

    您可以配置 InnoDB 缓冲池的各个方面以提高性能。

    • 理想情况下,您将缓冲池的大小设置为尽可能大的值,从而为服务器上的其他进程留出足够的内存来运行而无需过多的分页。 缓冲池越大,InnoDB 越像内存数据库,从磁盘读取一次数据,然后在后续读取期间访问内存中的数据。 请参阅第 15.6.3.2 节,“配置 InnoDB 缓冲区池大小”。

    可能(并且已经)写过关于buffer pool、它是如何工作以及如何使用optimize it 的书籍,所以我会停在那里,只留下这个关键字并让你参考文档。

    基本上,您的后续读取会将数据添加到可以重复使用的缓存中,直到它被其他数据替换(在您的情况下发生在第二天)。由于(对于 MySQL)这可以是对相关表的任何读取,而不必是您可能复杂的查询,它可能会使“预取”对您来说更容易。

    尽管以下内容附带免责声明,因为如果您更改配置,它显然会对您的服务器产生负面影响:默认 MySQL 配置非常(非常)保守,例如innodb_buffer_pool_size 系统设置对于大多数 15 岁以下的服务器来说太低了,所以不妨看看你的配置(或让你的系统管理员检查一下)。

    【讨论】:

    • 感谢您的回答。经过一些实验,在我们的例子中,它似乎是操作系统级别的文件系统缓存,与 MySQL 完全无关。
    【解决方案2】:

    我们做了一些实验,包括检查@Solarflare 回答中提到的系统的效果。在我们的案例中,我们得出结论,表面上的缓存是真实的,但它与 MySQL 完全无关。相反,它是由 Linux 磁盘缓存引起的。在我们的案例中,我们能够通过在获得结果前后手动刷新缓存并比较时间来验证这一点。

    【讨论】:

      猜你喜欢
      • 2010-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-15
      • 1970-01-01
      • 2014-06-25
      • 2016-09-14
      • 2015-02-05
      相关资源
      最近更新 更多