我正在使用AWS Redshift表保存有关函数调用的信息。 每行都有一个日期(时间戳类型),一个UID(varchar)和几个字段,例如持续时间,错误代码。 该表的大小约为2500万行,其中包含1000个不同的函数(每个函数具有不同的UID)。
我的问题是,简单的查询作为一个时间窗口中多个函数的调用计数会花费很多时间-通常为5-30秒。
我尝试了排序键和dist键的不同组合,但性能似乎仍然很相似:
将功能UID设置为dist键
以任意顺序设置日期,功能UID以及两者的组合的复合排序键。
我已经在桌子上运行了VACUUM和ANALYZE。 我还尝试添加/删除列压缩。
我仅使用一个dc2.large节点。
编辑:
表DDL为:
create table public."invocations_metrics_$mig"(
"function_uid" varchar(256) NOT NULL encode RAW DISTKEY
,"date" timestamp encode zstd
,"duration" double precision encode zstd
,"used_memory" integer encode zstd
,"error" smallint encode zstd
,"has_early_exit" boolean encode zstd
,"request_id" varchar(256) encode zstd
)
SORTKEY(date,function_uid);
一行示例:
"aca500c9-27cc-47f8-a98f-ef71cbc7c0ef","2018-08-15 13:43:28.718",0.17,27,0,false,"30ee84e1-a091-11e8-ba47-b110721c41bc"
查询:
SELECT
count(invocations_metrics_backup.function_uid) AS invocations,
max(invocations_metrics_backup.date) AS last_invocation,
invocations_metrics_backup.function_uid AS uid
FROM
invocations_metrics_backup
WHERE
function_uid IN (
<10 UIDs>
)
AND DATE >= '2018-08-20T10:55:20.222812'::TIMESTAMP
GROUP BY
function_uid
总时间为5秒。每个查询中的计数约为5000。 对于相同的查询(计数约为100万),需要30秒。
答案 0 :(得分:1)
首先,您需要至少使用2个节点。单个节点必须担当领导者和计算的双重职责。如果有2个或更多节点,您将获得一个免费的领导节点。
然后,按如下所示更改DDL,以消除排序键上的压缩:
CREATE TABLE public."invocations_metrics_$mig" (
"function_uid" varchar(256) NOT NULL ENCODE ZSTD,
"date" timestamp ENCODE RAW,
"duration" double precision ENCODE ZSTD,
"used_memory" integer ENCODE ZSTD,
"error" smallint ENCODE ZSTD,
"has_early_exit" boolean ENCODE ZSTD,
"request_id" varchar(256) ENCODE ZSTD
)
DISTSTYLE KEY
DISTKEY( function_uid )
SORTKEY ( date )
;
您还可以通过将唯一的UID映射到整数ID值并在查询中使用它来提高性能。 UID值使用起来效率很低。这些值随机出现,并且相对较宽,具有很高的熵。在排序,哈希聚合和哈希联接期间,它们非常昂贵。