Amazon Redshift - 获取游标命令挂在集群上

Amazon Redshift - Fetch Cursor Commands are hanging on Cluster

我们的 Redshift 集群存在性能问题。当运行集群上的某些查询时,查询计划中有一个中间步骤Fetch 200 in "SQL_CUR7"。此步骤导致查询挂起并阻塞集群。我们还没有定义这个游标,它似乎是由 Redshift 预先定义的。有人知道这种游标的作用吗?如果这可能是我们性能问题的原因?

该名称 SQL_CUR7 看起来像 Tableau 使用的命名,但它可能来自使用相同命名或正在复制的其他工具或用户。通常 Tableau 一次会获取 10,000 行,因此它可能不是 Tableau。关键是 FETCH 不是您的问题 - 它可能是提取背后的查询。

让我们从一些背景开始。当您 运行 查询 (select ...) 时,该查询的结果将发回给您 - 所有结果,无论大小。来自 Redshift 的数据量可能会淹没较小的计算机并使网络瘫痪。相反,可以声明一个“游标”并将查询结果临时存储在那里(在这种情况下,在 Redshift 领导节点上)。游标的内容由 FETCH 命令读取,该命令拉出指定数量的行。这样 reader 就不会被超出其处理能力的数据淹没。可以重复获取,直到读取游标的所有行。

游标由 DECLARE 语句定义,该语句还指定要 运行 填充游标的查询。但是,在游标的第一个 FETCH 发生之前,查询不是 运行。后续提取只会拉取更多在执行第一个 FETCH 时填充到游标中的数据。这样做的缺点是看起来像提取是 运行ning 的东西,它并没有告诉你很多关于正在发生的事情。它是 DECLARE 语句中定义的 SQL 运行,您需要找出这个 SQL 是什么才能找出发生了什么。

追溯这一点并不难。游标仅在事务打开时存在。这意味着 FETCH 和 DECLARE 在同一个事务 (xid) 中。于是找到'Fetch 200 in "SQL_CUR7"'的xid,用它在系统tableSVL_STATEMENTTEXT中找到这个交易(xid)发出的所有语句。 (Xid 可以在一段时间后重用,因此您可能只想查看获取执行前后的时间 window。)您应该看到定义“SQL_CUR7”的语句 - DECLARE “SQL_CUR7" ... - 这是 SQL 即 运行 正在获取时发生。

既然您看到了这个 SQL,那么事情可能会开始变得有意义,为什么事情会变得过载。查询可能很糟糕,并与其他一切交叉连接。它可能会用中间结果填满磁盘。查询可能会返回大量数据,并且它会使领导节点超载需要缓冲的数据。您可能需要进行一些诊断工作,但至少现在您拥有了需要分析的代码。