何时使用 SQL_NO_CACHE
Posted
技术标签:
【中文标题】何时使用 SQL_NO_CACHE【英文标题】:When to use SQL_NO_CACHE 【发布时间】:2013-09-17 15:34:40 【问题描述】:我正在检查我的查询,我一直在阅读有关如何在SELECT
查询中使用SQL_NO_CACHE
的文章。这让我很困惑,因为最后每篇文章对何时使用它都有不同的结论。我读过的一篇博客说,如果您有相同的查询并且是独一无二的,您应该使用它。在另一个博客上,我读到,当您必须提取永不改变的信息时,您应该使用它。
有人能解释一下什么时候使用这个是个好习惯吗?我知道以前有人问过,但是阅读很多文章并没有帮助,尤其是当人们说在不同情况下使用这种方法时。我做了一些理论上的情况,有人可以告诉我使用SQL_NO_CACHE
是否有益。谢谢你,我为一个重复的问题道歉。我真的很困惑。
假设一个网站存储其配置(即站点名称、站点描述、关键字),并且在每个页面上都会发出查询请求以提取每个页面上需要的信息。
您在登录检查期间选择userID
,查询仅在登录检查过程中运行。
您从表a
中选择一些数据来更新表b
中的字段,您是否应该在选择表a
时使用SQL_NO_CACHE
?
谢谢。
【问题讨论】:
【参考方案1】:SQL_NO_CACHE
只需在 SELECT 语句的 SELECT 部分之后和字段列表之前添加 SQL_NO_CACHE。如果启用并且查询被缓存,下面的第一个查询将使用查询缓存:
SELECT * FROM table WHERE search= 'keyword'; //lets take 1ms
下面的第二个查询不会使用查询缓存:
SELECT SQL_NO_CACHE * FROM table WHERE search= 'keyword'; //lets take ~0.2ms at 2nd time
这在对查询进行基准测试时特别有用;如果启用了查询缓存,尽管第一个查询可能需要一些时间,第二个和后续查询几乎是即时的。使用 SQL_NO_CACHE 可以确保不使用查询缓存,并且可以安全地比较结果时间。 SQL_NO_CACHE 提示为特定查询关闭 mysql 的内置查询缓存机制。您可以通过在高度动态的查询(例如关键字搜索或仅在夜间运行的报告)上使用此提示来帮助 MySQL 提高查询缓存的效率。 确保查询缓存已打开,否则不需要此命令。
什么 SQL_CACHE 和 SQL_NO_CACHE ?
SQL_CACHE 和 SQL_NO_CACHE 选项会影响查询缓存中查询结果的缓存。 SQL_CACHE 告诉 MySQL 将结果存储在查询缓存中,如果它是可缓存的,并且 query_cache_type 系统变量的值为 2 或 DEMAND。使用 SQL_NO_CACHE,服务器不使用查询缓存。它既不检查查询缓存以查看结果是否已缓存,也不缓存查询结果。 (由于解析器的限制,SQL_NO_CACHE 关键字前后必须有一个空格字符;换行符等非空格字符会导致服务器检查查询缓存以查看结果是否已缓存。)
如果启用'CACHE'并且数据库中的数据动态更新,则可以使用NO_CACHE,即不能依赖数据库数据缓存,例如:存储用户密码哈希我们不能依赖CACHE,因为数据经常有变化的可能性
有用场景的更新
1) 强制不使用缓存来测试查询速度
【讨论】:
如果我没记错的话,我看到了第二种情况:您执行了一个繁重的查询,并在 Redis 中缓存了几个小时的查询计算结果。在这种情况下,您不希望查询被缓存,因为这会浪费 RAM。【参考方案2】:我会选择禁止缓存的最明显时间是当我不希望缓存中的查询结果时(显然?)。
如果我只运行一次查询,那么就没有必要替换缓存中当前的数据来为永远不会从缓存中检索到的数据腾出空间。
第二种情况是我想运行低优先级查询 - 例如生成报告或部分备份 - 我的查询的性能并不重要,但重要的是它对数据库中发生的其他事情的破坏性最小(存在一些关于缓存访问争用的问题)。
第三种情况是有很多个简单的单表选择查询返回非常小的数据集(例如,使用简单的 ORM)。在这种情况下,使用查询缓存可能比完全绕过它要慢 - DBMS 将花费更多时间来管理查询缓存,而不是从缓冲池/系统缓存中读取数据。
正如 Tot 所说,缓存会影响任何分析/基准测试 - 但查询缓存并不是唯一缓冲/缓存数据的地方。
您从表 a 中选择一些数据来更新表 b 中的字段,您是否应该在表 a 的选择上使用 SQL_NO_CACHE?
没有。当底层数据被修改时,缓存会自动失效(这是简单查询的大部分成本来源)。
【讨论】:
如果我只运行一次查询,那么就没有必要替换缓存中当前的数据来为永远不会从缓存中检索到的数据腾出空间。 是的,终于有道理了。如果在任何时候,“开启缓存”的查询返回的数据与“关闭缓存”的查询返回的数据不同,那么结论只能是:“MySQL 不是数据库”。【参考方案3】:为了回答您的问题,您首先必须了解 MySQL 查询缓存的工作原理。可以在here 找到一篇非常好的文章。一个关键方面是缓存是synchronized with the data:
查询缓存不返回陈旧数据。修改表时, 查询缓存中的所有相关条目都会被刷新。
在您的用例中,我没有发现不将查询缓存与SQL_NO_CACHE
一起使用的任何真正目的。使用此选项有分析或避免将大数据写入有限查询缓存等原因,但我认为这里不是这种情况。
【讨论】:
我想知道这个。除非我使用 SQL_NO_CACHE,否则 MySQL Workbench 几乎总是返回过时的数据。但是命令提示符 MySQL shell 很好。【参考方案4】:这个问题的答案是有效的;然而,从 MySQL 5.7.20 开始,查询缓存已被贬值。有关详细信息,请参阅MySQL Documentation。
【讨论】:
【参考方案5】:我唯一一次使用它是在分析查询时 (EXPLAIN extended...
)。
当多次运行查询时(“预热”服务器的一个非常重要的步骤),它将被缓存,因此分析器将输出错误的结果。
根据我也使用的情况:
SET SESSION query_cache_type = OFF
【讨论】:
以上是关于何时使用 SQL_NO_CACHE的主要内容,如果未能解决你的问题,请参考以下文章