我在亚马逊RedShift上有一个视图,它正常工作了几个月.有一天,它突然停止工作,并出现错误:

error:  Assert
code:      1000
context:   ht0_3 != NULL - Hash table for subplan does not exist.

查询本身有3个CTE,每个CTE从一个表中 Select 不同的行.然后将它们连接在一起.每个CTE本身都工作得很好,但当我try 加入它们时,我得到了这个错误(尽管以前它工作得很好)

Internet上有关于此错误的近0条信息.如果我将其中一个CTE留在联接之外,错误是可以避免的,但我需要在结果表中包含该信息.

UPD:我设法解决了这个问题,但我仍然不知道为什么会发生错误.以下是导致问题的查询和重写后的工作版本.

CREATE TABLE bad_table AS (
    SELECT DISTINCT
        t.table_schema,
        t.table_name,
        t.column_name
    FROM svv_columns t
    WHERE true
        AND t.table_name not like '%test%'
        AND t.table_schema in ('table_1','table_2', ... , 'table_30')
)

但是,以以下方式重写的查询运行良好:

CREATE TABLE failing_table AS (
    SELECT DISTINCT
        t.table_schema,
        t.table_name,
        t.column_name
    FROM svv_columns t
    WHERE true
        AND t.table_name not like '%test%'
        AND (t.table_schema in ('table_1', ... , 'table_10')
            or t.table_schema in ('table_11', ... , 'table_20')
            or t.table_schema in ('table_21', ... , 'table_30'))
    )

有趣的是,失败的AND条件在两个不同的CTE中使用.在一个CTE中,它是有效的(在in子句中列举了30个表,还有更多),而在另一个CTE中(只有30个表)失败了.

总而言之,我希望听到以下两个问题的解释:

  1. 为什么视图在一个月内一直运行良好,然后突然开始抛出这个错误.未对数据库设置或视图本身进行任何更改.
  2. 为什么相同的AND条件在所有in个条件都被一起枚举的情况下失败,但当它们由or运算符连接时工作得很好.

推荐答案

使用查询编译器很有趣.

首先,查询不应该抛出错误,很可能是通过对RedShift集群的更新引入的.查看RS版本更改时是否发生了更新.应将该错误通知AWS.如果您想要确凿的证据或需要解决此问题,也可以回滚版本.红移代码会定期更新,有时会出现错误.

当您运行任何查询时,每个数据库都会编译和优化查询,以提供最快的执行时间.您以一种方式编写查询,但数据库决定以另一种方式执行它.这是正常的.RedShift有几个不同的优化器(优化方法),可以从许多因素(表元数据、查询语法、...和AI学习过程)中进行 Select 并做出 Select .因此,这种人工智能可能是引入这种变化的原因,但我怀疑首先是代码更新.

现在到您的确切代码.我以前见过这种情况--IN列表长度是优化器组织代码的一个因素.短IN列表将更改为OR相等性判断列表[X IN(‘A’,‘B’)将更改为X=‘A’或X=‘B’].它之所以这样做,是因为执行起来更快.对于较长的IN列表,RedShift将建立一个包含其中所有元素的数据 struct (类似于伪表),并执行类似联接的操作来进行比较.对于较长的值列表,这会更快.当我最后一次使用客户端和AWS进行调试和发出这样的命令时,中断点大约是IN列表中的10个值,但那是几年前的事了.

因此,我怀疑,您修改后的代码之所以有效,是因为您有一个很长的IN列表,这会导致优化器做出不同的 Select 并避免引入的错误.当然,这只是一种猜测,但基于处理类似问题的经验.您可以比较这两个查询的Exain计划,我希望您会看到,由于优化器的 Select ,它们的计划有所不同.

Sql相关问答推荐

当编号和版本的唯一状态更改时报告

GROUP BY和GROUP_CONCAT用于计算比赛排名

在postgres中动态计算出现次数并插入到json中

在Postgres中实现合并功能的干净方法,因为当目标/源不匹配时

通过之前的连接-这是Oracle的错误吗?

基于唯一值在Access查询中创建计数器

使用Kotlin Exposed SQL DSL Select 多个值并排序

带上最后日期(结果)

多条件SQL排序行为

如何使用不重复的单个顶级字段(列)向json数组 Select 多行

按连续相等值分组排序

查找滑动窗口框架中的最大和最小列值

如何根据 SQL 中的阈值标记一个集群中的所有值?

具有分组条件的不同计数 (DAX)

PostgreSQL分割字符串为子词并判断其是否存在于其他字符串中

使用给定的变量对在循环中执行更新语句

如果 SQL 中不存在数据,如何根据某个 ID 为所有日期添加前一行

根据开始/结束标记将 GROUP_ID 分配给行

SQL - 使用子查询返回多行的 LIKE 命令

Postgres 窗口函数未按预期工作