Amazon Redshift 集群中的表使用的磁盘存储空间与我预期的不同。如何计算 Amazon Redshift 集群中的磁盘存储空间和表大小?

对于位于不同 Amazon Redshift 集群中的两个表,即使它们使用相同的数据定义语言 (DDL) 语句创建并且包含相同数量的行,分配给它们的磁盘存储空间也可能存在很大差异。在下面的场景中,每个表占用的磁盘存储空间差异由以下因素决定:

  • 每个 Amazon Redshift 集群上填充的切片数量
  • 每个表使用的表段的数量

最小磁盘空间是表可在 Amazon Redshift 集群上拥有的最小数据占用空间。在分析集群存储使用情况或调整 Amazon Redshift 集群大小时,您可以检查最小表大小。您可以使用以下公式计算最小磁盘空间:

  • 对于使用 KEY 或 EVEN 分配方式创建的表:
    最小表大小 = 数据块大小 (1MB) *(用户列数 + 3 个系统列)* 填充切片数 * 表段数。
  • 对于使用 ALL 分配方式创建的表:
    最小表大小 = 数据块大小 (1MB) *(用户列数 + 3 个系统列)* 集群节点数 * 表段数。

如果两个 Amazon Redshift 表具有以下共同属性:

  • 使用相同的 DDL 语句创建
  • 包含相同数量的行
  • 未经过手动修改

则表磁盘存储空间分配可能会因以下因素而异:

  • 由表填充的集群切片数(对于使用 EVEN 和 Key 分配方式创建的表)
  • 集群中的节点数(对于使用 ALL 分配方式分配的切片)
  • 表中的段数

如果 Amazon Redshift 表具有排序键,则该表中会有两个段:一个已排序的段和一个未排序的段。如果 Amazon Redshift 表中没有排序键,则所有数据都未经过排序,因此该表有一个未排序的段。

在将数据添加到具有排序键的现有表时,新数据会保留在包含未排序数据的单独段中,也就是说,新数据不会插入到已使用排序键排序的原始段中,直到执行 VACUUM 操作。有关更多信息,请参阅管理已合并行的数量

注意:VACUUM 操作会将数据与已排序的数据合并。但表仍将保留未排序的段,以便用于将来加载数据。

变量 number_of_table_segments 是以下三个值(表示要为 Amazon Redshift 表分配的表段数)之一:

    0:表未加载过;为零表段分配磁盘空间。

    1:没有排序键的表已加载过一次或多次。

    2:具有排序键的表已加载过一次或多次

最小表大小计算示例:

如果表具有 125 个用户列,并且在具有 16 个切片的集群中具有排序键,则要计算表可以填充所有 16 个切片的最小大小,可使用如下公式:

1MB * (125 + 3) * 16 * 2 = 4096MB

如果表使用 DDL 语句创建,且该表驻留在填充两个切片的集群上,则以下最小表大小计算结果表明该表使用的磁盘存储空间明显更少:

1MB * (125 + 3) * 2 * 2 = 512MB

如果表使用同一 DDL 语句创建,且该表驻留在填充 64 个切片的集群上,则以下最小表大小计算结果表明该表使用的磁盘存储空间明显更多:

1MB * (125 + 3) * 64 * 2 = 16384 MB

根据最小表大小示例,表的大小可根据集群上填充的切片数量增大或缩小。 

1. 使用以下查询确定分配给 Amazon Redshift 集群中表的磁盘空间量:

SELECT ti.database,
      ti.schema||'.'||ti."table"AS tablename,
      ti.size
FROM svv_table_info ti;

2. 运行以下查询计算表的最小表大小:

WITH 
tbl_ids AS
(SELECT DISTINCT oid
FROM pg_class c
WHERE relowner>1
AND relkind='r'),
stp AS
(SELECT id,sum(ROWS)sum_r,sum(sorted_rows)sum_sr,min(ROWS)min_r,
max(ROWS)max_r,nvl(count(DISTINCT slice),0)pop_slices
FROM stv_tbl_perm
WHERE id IN (SELECT oid FROM tbl_ids)
AND slice<6400
GROUP BY id),
colenc AS
(SELECT attrelid,sum(CASE WHEN a.attencodingtype=0 THEN 0 ELSE 1 END)
AS encoded_cols,count(*)AS cols
FROM pg_attribute a
WHERE a.attrelid IN (SELECT oid FROM tbl_ids)
AND a.attnum>0
GROUP BY a.attrelid),
cluster_info AS
(SELECT COUNT(DISTINCT node) node_count
FROM stv_slices)
SELECT ti.database,
ti.schema||'.'||ti."table"AS tablename,
ti.diststyle,
ti.sortkey1,
ti.size current_size,
nvl(CASE
WHEN stp.sum_r=stp.sum_sr
OR stp.sum_sr=0 THEN CASE
WHEN"diststyle"='EVEN' THEN
CASE
WHEN ti.sortkey1 != '' THEN (stp.pop_slices*(colenc.cols+3)*2)
ELSE (stp.pop_slices*(colenc.cols+3))
END
WHEN substring("diststyle",1,3)='KEY' THEN
CASE
WHEN ti.sortkey1 != '' THEN (stp.pop_slices*(colenc.cols+3)*2)
ELSE (stp.pop_slices*(colenc.cols+3))
END
WHEN"diststyle"='ALL' THEN
CASE
WHEN ti.sortkey1 != '' THEN cluster_info.node_count*(colenc.cols+3)*2
ELSE cluster_info.node_count*(colenc.cols+3)
END
END
ELSE CASE
WHEN"diststyle"='EVEN'THEN(stp.pop_slices*2*(colenc.cols+3))
WHEN substring("diststyle",1,3)='KEY'
THEN(stp.pop_slices*(colenc.cols+3)*2)
WHEN"diststyle"='ALL'
THEN(cluster_info.node_count*(colenc.cols+3)*2)
END
END,0) AS minimum_size
FROM svv_table_info ti
LEFT JOIN stp ON stp.id=ti.table_id
LEFT JOIN colenc ON colenc.attrelid=ti.table_id
CROSS JOIN cluster_info
WHERE ti.schema NOT IN('pg_internal')
ORDER BY ti.size DESC;

要确定使用场景的最佳集群配置,请参阅 Amazon Redshift 中的集群和节点以及数据仓库系统架构


此页面对您有帮助吗? |

返回 AWS Support 知识中心

需要帮助?请访问 AWS 支持中心

发布时间:2016 年 4 月 15 日

更新时间:2018 年 7 月 6 日