我们使用此处定义的推荐方法来执行" upserts": http://docs.aws.amazon.com/redshift/latest/dg/merge-replacing-existing-rows.html
加载一个只有150行的文件大约需要两分钟。几乎所有这些时间都花在了这个删除操作上:
delete
from
measurement using measurement_temp
where
measurement.measurement_tag_id = measurement_temp.measurement_tag_id
and measurement.date_time = measurement_temp.date_time
即使临时表为空,此操作仍需要将近两分钟才能完成。
在所有桌子上运行完全真空后仍然很慢。
谓词中的两个列都是复合排序键的一部分,而measurement_tag_id是分配键,因此我不清楚为什么Redshift需要这么长时间。
此表的架构如下所示:
create table measurement(
measurement_tag_id integer not null distkey,
date_time timestamp not null,
value_avg decimal(8,3),
value_min decimal(8,3),
value_max decimal(8,3),
value_std_dev decimal(8,3),
failed_qa_rule_id integer,
primary key(measurement_tag_id, date_time),
foreign key (measurement_tag_id) references measurement_tag(measurement_tag_id),
foreign key (failed_qa_rule_id) references qa_rule(qa_rule_id)
)
compound sortkey(measurement_tag_id, date_time);
以下是DELETE的查询计划:
XN Hash Join DS_DIST_NONE (cost=9.30..3368957513.17 rows=451945 width=6)
Hash Cond: (("outer".date_time = "inner".date_time) AND ("outer".measurement_tag_id = "inner".measurement_tag_id))
-> XN Seq Scan on measurement (cost=0.00..26844282.88 rows=2684428288 width=18)
-> XN Hash (cost=6.20..6.20 rows=620 width=12)
-> XN Seq Scan on measurement_temp (cost=0.00..6.20 rows=620 width=12)
等效的SELECT几乎立即返回。这是其查询计划:
explain
select * from measurement as m
join measurement_temp as mt on m.measurement_tag_id = mt.measurement_tag_id and m.date_time = mt.date_time
XN Merge Join DS_DIST_NONE (cost=0.00..40266436.05 rows=451945 width=144)
Merge Cond: (("outer".measurement_tag_id = "inner".measurement_tag_id) AND ("outer".date_time = "inner".date_time))
-> XN Seq Scan on measurement m (cost=0.00..26844282.88 rows=2684428288 width=68)
-> XN Seq Scan on measurement_temp mt (cost=0.00..6.20 rows=620 width=76)
所以DELETE正在执行散列连接,而SELECT正在使用更快的合并连接。
任何想法如何加快速度?大多数情况下,没有任何东西可以删除(而且它仍然很慢),所以我可以先添加一个SELECT查询来检查是否需要删除任何东西,但它是重新加载现有数据仍然会很慢。