首次运行查询非常慢

Posted

技术标签:

【中文标题】首次运行查询非常慢【英文标题】:First-run of queries are extremely slow 【发布时间】:2018-03-29 16:26:44 【问题描述】:

我们的 Redshift 查询在第一次执行时非常很慢。随后的执行速度要快得多(例如,45 秒 -> 2 秒)。在调查了这个问题之后,查询编译似乎是罪魁祸首。这是一个已知问题,甚至在 AWS Query Planning And Execution Workflow 和 Factors Affecting Query Performance 页面上也有提及。亚马逊本身对查询缓存的工作方式非常 tight lipped (tl;博士,这是一个你不应该担心的神奇黑匣子)。

我们尝试的其中一个方法是增加我们拥有的节点数量,但是我们并不期望它能够解决任何问题,因为无论如何查询编译都是单节点操作。它没有解决任何问题,但它是一个有趣的消遣。

如前所述,这是一个已知问题,但是,在任何在线讨论的地方,唯一的收获要么是“这只是你必须使用 Redshift 才能忍受的事情”或“这是一个超级笨拙的解决方法,它只适用于时间,因为我们不知道查询缓存是如何工作的”。

我们可以做些什么来加快编译过程或以其他方式处理这个问题?到目前为止,找到的最佳解决方案是“预先运行您可能希望在给定日期按计划运行的每个查询”,这不是很好,特别是考虑到我们对查询缓存的工作原理知之甚少.

【问题讨论】:

冷缓存问题并非 Redshift 独有。如果你想保持温暖,你需要一个脚本来偶尔戳一下它。 我们也面临着与迈克相同的问题。如果有人有任何替代解决方案或任何解决方案,请告诉我们。 @jai 物有所值 - 我们从未找到解决此问题的方法。企业认为这是一个交易破坏者,我们改用 Snowflake 【参考方案1】:

有 3 件事需要考虑

    任何查询的第一次运行都会导致查询被“编译” 红移。这可能需要 2-20 秒,具体取决于它的大小。 相同查询的后续执行使用相同的编译代码, 即使 where 子句参数发生变化也不会重新编译。 运行查询时,数据测量为标记为“热” 反对它,并缓存在红移内存中。你不能(可靠地)手动 以任何方式清除它,除非重新启动集群。 Redshift 将“缓存结果”,具体取决于您的 Redshift 参数 (默认启用)redshift 将快速返回相同的结果 对于完全相同的查询,如果基础数据没有改变。如果 您的查询包括 current_timestamp 或类似的,那么这将 如果从缓存中停止。这可以通过SET enable_result_cache_for_session TO OFF; 关闭。

考虑到您的问题,您可能需要运行一些示例查询来预编译或重新设计您的查询(我猜您正在构建一些动态查询,这会极大地改变查询的形状)。 根据我的经验,更多的节点会增加编译时间。这个过程发生在主节点而不是数据节点上,并且通过考虑更多的数据节点而变得更加复杂。

【讨论】:

【参考方案2】:

该查询实际上可能没有第二次运行 - 相反,Redshift 只是为同一查询返回相同的结果。

这可以通过关闭缓存来测试。运行这个命令:

SET enable_result_cache_for_session TO OFF;

然后,运行两次查询。每次执行都应该花费相同的时间。

结果缓存非常适合重复查询。与其对第一次执行“慢”感到失望,不如对后续缓存的查询“快”感到高兴!

【讨论】:

也许 - 但 2 秒对于缓存结果查询来说有点慢,你不觉得吗?除非那 2s 可能包括网络时间。通常这些是 @JonScott FWIW 我引用的“2 秒”不是经过严格测试的值。更多“几个数量级差异”的例子

以上是关于首次运行查询非常慢的主要内容,如果未能解决你的问题,请参考以下文章

使用 order by 时,Mysql 查询运行非常慢

Sql Azure:WITH 语句查询的性能非常慢

使用 sum 和 group by 选项的 Mysql 查询运行速度非常慢

MySQL Left Join 运行速度非常慢,拆分为 2 个查询要快得多

mysql重启之后首次查询很慢,求问是啥原因引起的

为啥这个 mySQL 查询非常慢?