减少 CPU 利用率的 Redshift 查询性能
Redshift Query Performance to reduce CPU utilisation
我想大致了解一下如何优化 redshift 数据库中的查询性能,我有大量包含大量连接的查询,我确实理解使用排序和 Dist 键可以实现,但有没有一种方法我们可以遵循它以获得一些最佳结果。
在 table 中查看什么以及如何在 redshift 中进行查询优化?
为了制定特定的优化计划,需要寻找或采取哪些必要步骤?
任何指导都会有很大帮助
改进了许多关于 Redshift 的查询后,我可以向您指出一些事情。首先让我列出一些工具/技术,以确保您的工具箱中有这些。
- 能够阅读和解释计划并找到预期的高成本点
- 知道在哪里可以找到查询“实际”执行报告
- 了解系统 table 以查找加入、分发和磁盘 io 报告
了解了这些之后,让我们看看 Redshift 上许多查询出现问题的地方。我将尝试按帕累托顺序列出这些,但其中任何一个或组合都会产生重大问题。
#1 - 查询中间的脂肪。加入时,可以将正在操作的行数扩大很多倍。交叉连接是发生这种情况的一种明显方式,但通常不会发生这种情况。如果连接条件创建多对多连接模式,行数可以扩展。当 table 大小非常大时,“乘法”会产生荒谬的数据大小。解释计划可以显示这一点,但并非总是如此——使用 DISTINCT 和 GROUP BY 可以“隐藏”正在运行的数据集的真实大小。在连接树上执行 SELECT COUNT(*) 可以帮助显示它有多大。如果稍后的连接正在折叠行(查询优化器失败?),您可能还可能需要查看连接树的一部分。 Redshift 是一个列式数据库,不能很好地创建数据 - 这包括在查询执行期间。
#2 - 大量数据的分布。 Redshift 是一个集群,节点通过以太网电缆连接在一起,这些连接是集群中最慢的部分。查询优化器做了很多工作来最小化需要在网络中移动的数据量。但是,它并不像您那样了解您的数据,而且并不总是能做到这一点。查看您获得的连接类型 - 是否需要分发?分发了多少数据?此外,group by(和 window 函数)需要合并行,因此可能需要重新分配才能完成。进入聚合步骤的数据集有多大?
在网络上移动大量数据会很慢。困难在于如何减少这种运动并不总是很清楚。当涉及到“连接”数据的结果分布时,像您所说的大型连接树可以做“奇怪”的事情。一次执行一个连接,这些连接发生的顺序可能很重要。查询优化器正在对连接的顺序以及如何组织每个连接的结果数据做出许多决定。它所做的选择基于它在 table 元数据中看到的内容,因此元数据的完整性很重要。 WHERE 条件也会影响优化器的选择。有许多交互方式可以在此处逐条列出。最好的建议是查看每个步骤的性能,看看数据分布是否是一个因素。然后控制数据在查询执行中的分布方式。这可能意味着更改连接树,甚至将查询分解为具有临时 table 的几个具有分布集的查询,以便最大限度地减少数据移动。
#3 过多的 IO 流量 - 虽然不像网络那么慢,但磁盘 IO 子系统通常是一个瓶颈。这表现在几个方面。您是否从磁盘读取了比需要更多的数据? (元数据是最新的?)您是否需要一个冗余的 WHERE 子句来消除数据? (冗余 WHERE 子句在功能上不需要,但被添加了,因此 Redshift 可以执行元数据比较,这将减少扫描时读取的数据。)数据溢出是磁盘 IO 紧张的另一种方式(这可以追溯到 #1) .如果数据需要溢出到磁盘,它会大大降低磁盘 IO 性能。好好使用您的元数据和 Where 子句。
现在这 3 个方面经常联合起来扼杀你的表现。从您的 table 中读取太多行,通过网络将所有这些额外的行连接在一起,同时还生成许多新行。此数据不适合内存,因此现在 Redshift 需要溢出到磁盘以完成查询。在这些条件下,事情变慢得非常快。
最后,我列出的这些因素是 Redshift 的集群范围“资源”。如果一个查询占用了其中的很多查询,那么同时 运行ning 的其他查询就更少了。经常发生的情况是,集群上的查询编写者遵循相似的模式(好或坏),当他们的模式在一个轴上成本高昂时,他们的许多查询在同一轴上成本高昂。这显示为在 运行 孤立时工作“正常”的查询,但在其他人使用集群时非常糟糕。这通常意味着许多查询有助于将集群推向某些有限资源的“边缘”。您可以查看系统 table 以查看汇总的 IO 或网络流量以查看这些效果。
好的查询是:
- 在执行过程中不要产生很多新的“行”(中间不是肥肉)
- 将大型数据集保留在“节点上”,并且仅在数据显着减少后才重新分发数据
- 不要从磁盘读取不必要的数据,也不要溢出
问题是做所有这些并不总是可行的诀窍是不要过度订阅您拥有的集群资源。
我想大致了解一下如何优化 redshift 数据库中的查询性能,我有大量包含大量连接的查询,我确实理解使用排序和 Dist 键可以实现,但有没有一种方法我们可以遵循它以获得一些最佳结果。
在 table 中查看什么以及如何在 redshift 中进行查询优化? 为了制定特定的优化计划,需要寻找或采取哪些必要步骤?
任何指导都会有很大帮助
改进了许多关于 Redshift 的查询后,我可以向您指出一些事情。首先让我列出一些工具/技术,以确保您的工具箱中有这些。
- 能够阅读和解释计划并找到预期的高成本点
- 知道在哪里可以找到查询“实际”执行报告
- 了解系统 table 以查找加入、分发和磁盘 io 报告
了解了这些之后,让我们看看 Redshift 上许多查询出现问题的地方。我将尝试按帕累托顺序列出这些,但其中任何一个或组合都会产生重大问题。
#1 - 查询中间的脂肪。加入时,可以将正在操作的行数扩大很多倍。交叉连接是发生这种情况的一种明显方式,但通常不会发生这种情况。如果连接条件创建多对多连接模式,行数可以扩展。当 table 大小非常大时,“乘法”会产生荒谬的数据大小。解释计划可以显示这一点,但并非总是如此——使用 DISTINCT 和 GROUP BY 可以“隐藏”正在运行的数据集的真实大小。在连接树上执行 SELECT COUNT(*) 可以帮助显示它有多大。如果稍后的连接正在折叠行(查询优化器失败?),您可能还可能需要查看连接树的一部分。 Redshift 是一个列式数据库,不能很好地创建数据 - 这包括在查询执行期间。
#2 - 大量数据的分布。 Redshift 是一个集群,节点通过以太网电缆连接在一起,这些连接是集群中最慢的部分。查询优化器做了很多工作来最小化需要在网络中移动的数据量。但是,它并不像您那样了解您的数据,而且并不总是能做到这一点。查看您获得的连接类型 - 是否需要分发?分发了多少数据?此外,group by(和 window 函数)需要合并行,因此可能需要重新分配才能完成。进入聚合步骤的数据集有多大?
在网络上移动大量数据会很慢。困难在于如何减少这种运动并不总是很清楚。当涉及到“连接”数据的结果分布时,像您所说的大型连接树可以做“奇怪”的事情。一次执行一个连接,这些连接发生的顺序可能很重要。查询优化器正在对连接的顺序以及如何组织每个连接的结果数据做出许多决定。它所做的选择基于它在 table 元数据中看到的内容,因此元数据的完整性很重要。 WHERE 条件也会影响优化器的选择。有许多交互方式可以在此处逐条列出。最好的建议是查看每个步骤的性能,看看数据分布是否是一个因素。然后控制数据在查询执行中的分布方式。这可能意味着更改连接树,甚至将查询分解为具有临时 table 的几个具有分布集的查询,以便最大限度地减少数据移动。
#3 过多的 IO 流量 - 虽然不像网络那么慢,但磁盘 IO 子系统通常是一个瓶颈。这表现在几个方面。您是否从磁盘读取了比需要更多的数据? (元数据是最新的?)您是否需要一个冗余的 WHERE 子句来消除数据? (冗余 WHERE 子句在功能上不需要,但被添加了,因此 Redshift 可以执行元数据比较,这将减少扫描时读取的数据。)数据溢出是磁盘 IO 紧张的另一种方式(这可以追溯到 #1) .如果数据需要溢出到磁盘,它会大大降低磁盘 IO 性能。好好使用您的元数据和 Where 子句。
现在这 3 个方面经常联合起来扼杀你的表现。从您的 table 中读取太多行,通过网络将所有这些额外的行连接在一起,同时还生成许多新行。此数据不适合内存,因此现在 Redshift 需要溢出到磁盘以完成查询。在这些条件下,事情变慢得非常快。
最后,我列出的这些因素是 Redshift 的集群范围“资源”。如果一个查询占用了其中的很多查询,那么同时 运行ning 的其他查询就更少了。经常发生的情况是,集群上的查询编写者遵循相似的模式(好或坏),当他们的模式在一个轴上成本高昂时,他们的许多查询在同一轴上成本高昂。这显示为在 运行 孤立时工作“正常”的查询,但在其他人使用集群时非常糟糕。这通常意味着许多查询有助于将集群推向某些有限资源的“边缘”。您可以查看系统 table 以查看汇总的 IO 或网络流量以查看这些效果。
好的查询是:
- 在执行过程中不要产生很多新的“行”(中间不是肥肉)
- 将大型数据集保留在“节点上”,并且仅在数据显着减少后才重新分发数据
- 不要从磁盘读取不必要的数据,也不要溢出
问题是做所有这些并不总是可行的诀窍是不要过度订阅您拥有的集群资源。