【发布时间】:2021-05-31 12:51:03
【问题描述】:
我有一个表,其中包含有关我数据库中不同表的信息。对于其中的每个表,我希望(每天)进行定期日志记录。问题是我已经使用 for 循环完成了这项工作,并且在 Redshift 中执行需要花费大量时间。我给出了用于创建表、日志记录表和使用 for 循环的过程的查询。 请建议一种替代方法来实现这一点而无需 for 循环。 包含不同表信息的表结构:
CREATE TABLE public.info_schema_table
(
info_schema_name character varying(200) ENCODE lzo,
info_object_name character varying(200) ENCODE lzo,
info_object_type character varying(200) ENCODE lzo,
info_object_full_name character varying(400) ENCODE lzo
)
DISTSTYLE EVEN;
这里,object name 是指表名,object_type 包含表是视图还是表,object_full_name 存储表的连接名称和模式,即如果模式名称是“test_schema”,那么全名是“test_schema” .table_name”。需要存储日志的表结构:
CREATE TABLE public.redshift_logging_table
(
log_schema_name character varying(30) ENCODE lzo,
log_object_name character varying(30) ENCODE lzo,
log_object_type character varying(30) ENCODE lzo,
log_refresh_date date ENCODE az64,
log_refresh_count bigint ENCODE az64,
log_total_count bigint ENCODE az64
)
DISTSTYLE EVEN;
这里,refresh_date 存储记录日期,refresh_count 存储在特定日期插入表中的记录数,total_count 包含到记录日期为止表中的记录总数。
为了澄清,这里是 info_schema_table 的一个示例记录:
这是我用来填充记录表的过程:
CREATE OR REPLACE PROCEDURE public.REDSHIFT_LOGGING_PROCEDURE()
AS $$
DECLARE
var_total_count bigint;
var_records_today bigint;
my_row record;
my_cursor CURSOR
FOR select info_schema_name, info_object_name, info_object_type , info_object_full_name from INFO_SCHEMA_TABLE ;
BEGIN
open my_cursor;
LOOP
FETCH my_cursor INTO my_row;
EXIT WHEN NOT FOUND;
BEGIN
EXECUTE ' select count(1)::bigint from '||my_row.INFO_OBJECT_FULL_NAME INTO var_total_count;
var_records_today=var_total_count-(select log_total_count from REDSHIFT_LOGGING_TABLE where REFRESH_DATE=current_date-1 and LOG_OBJECT_NAME=my_row.INFO_OBJECT_NAME);
insert into REDSHIFT_LOGGING_TABLE
(LOG_SCHEMA_NAME,LOG_OBJECT_NAME,LOG_OBJECT_TYPE,LOG_REFRESH_DATE, LOG_REFRESH_COUNT, LOG_TOTAL_COUNT )
values
(my_row.info_schema_name, my_row.info_object_name, my_row.info_object_type , current_date, var_records_today, var_total_count);
END;
END LOOP;
END;
$$ LANGUAGE plpgsql
SECURITY INVOKER;
所有表的记录数每天都在增加,因此在任何特定日期插入的记录始终 >=0。
问题是,此过程有效,但仅适用于 info_schema_table 中的小记录,如果我对大约 1000 条记录运行它,即使在一小时内,该过程也不会在 Redshift 上完成。
请建议一种替代方法来执行它而不使用 for 循环。谢谢。
【问题讨论】:
-
我首先要将此循环重写为单个(希望是)INSERT 操作。似乎可以实现,给我一些时间。
-
未来你也可以考虑改变 diststyles 以避免在节点之间移动数据。
标签: sql for-loop amazon-redshift plpgsql procedure