AWS Redshift:出现“and not true”子句时删除挂起

Posted

技术标签:

【中文标题】AWS Redshift:出现“and not true”子句时删除挂起【英文标题】:AWS Redshift: delete hangs while the "and not true" clause appeared 【发布时间】:2019-09-17 09:13:16 【问题描述】:

我在 aws-redshift 上执行了一个删除的 sql,它已经执行了几个小时但仍未完成。

我尝试将 VACUUM 表进行 100% 排序,但这没有任何意义。

错误的 sql 是:

delete from tmp_table
    using my_table
    where (my_table.id = tmp_table.id)
    and (not true);

我交换了这两张表,它仍然挂起。

delete from my_table
    using tmp_table
    where (my_table.id = tmp_table.id)
    and (not true);

我什至交换了条件的位置,将not true替换为false,不起作用。

最后发现这条sql也挂了:

delete from tmp_table using my_table where false;

我还执行了一些其他的 sql,它们运行得非常快:

select count(*) from tmp_table
join my_table
     on (my_table.id = tmp_table.id)
     and (not true);
delete from my_table
 using tmp_table
     where (my_table.id = tmp_table.id)
     and (true);

我知道我不需要执行删除 sql,因为条件始终为 false,它什么也不删除。我只是想知道什么会导致sql挂起。

【问题讨论】:

你删除了多少行?删除可能非常昂贵,尤其是在列式数据库中。 通常在 Redshift 上删除的更好方法是选择您想要的行到一个新表中,删除或重命名原始表,然后使用原始表重命名新表名称,即替换它。不要忘记,一旦您在 Redshift 上执行了大量删除操作,您还需要对表进行 VACUUM。 【参考方案1】:

当 SQL 在任何数据库上“挂起”时,99% 的情况是因为其他进程锁定了对象。

在您的情况下,由于您正在试验,您可能多次运行相同的语句并且您尝试从中删除的表有一个锁。

为了列出 Redshift 中的锁,您可以使用此查询

SELECT 
  current_time, 
  c.relname, 
  l.database, 
  l.transaction, 
  l.pid, 
  a.usename, 
  l.mode, 
  l.granted
FROM pg_locks l 
JOIN pg_catalog.pg_class c ON c.oid = l.relation
JOIN pg_catalog.pg_stat_activity a ON a.procpid = l.pid
WHERE l.pid <> pg_backend_pid();

当您确定哪个进程锁定了表并确保可以将其杀死后,您可以这样做以消除瓶颈。

select pg_cancel_backend(<pid of the process from above query>)

【讨论】:

在这种情况下,根据您要删除的数据量,创建一个新表可能会更快,我已经在我对这个问题的回答中解释了如何***.com/questions/57065014/…【参考方案2】:

你可以这样形成

delete from my_table
where id in (
    select id from tmp_table
    )

【讨论】:

以上是关于AWS Redshift:出现“and not true”子句时删除挂起的主要内容,如果未能解决你的问题,请参考以下文章

AWS Redshift 查询过长异常

AWS Redshift 列“view_table_B.cost”必须出现在 GROUP BY 子句中或用于聚合函数

AWS Redshift 默认时间戳

AWS Redshift 节点故障 - 尽管有多个节点,但整个集群是不是不可用?

使用 SQL Workbench 将 csv 文件导入 AWS Redshift 数据库

无法从 AWS lambda 连接 AWS redshift