2

我目前正在开展一个项目,该项目每周收集客户人口统计数据并将增量(来自前几周)存储为新记录。这个过程将包含 160 个变量和几亿人(我的管理层和一家咨询公司需要这样做,尽管大约 100 个变量看似无用)。这些变量将从我们 Teradata 仓库中的 9 个不同表中收集。

我打算把它分成两张桌子。

  1. 包含常用人口统计数据的表格(约 60 个变量来自 3 个表格)
    • 标准化(1 个客户 ID 并为每个人口统计变量添加日期)
  2. 具有很少或未使用的人口统计数据的表格(来自 6 个表格的约 100 个变量)
    • 标准化(1 个客户 ID 并为每个人口统计变量添加日期)

MVC 用于尽可能多地节省空间,因为由于备份限制,它将存在的数据库的大小受到限制。(请注意,客户 ID 目前消耗表 1 大小的 30% (3.5gb),因此额外的表会增加存储成本)

将通过查找与分析师选择的日期相关的最新记录来访问表:

SELECT cus_id,demo
    FROM db1.demo_test 
    WHERE (cus_id,add_dt) IN (
        SELECT cus_id, MAX(add_dt) 
            FROM db1.dt_test 
            WHERE add_dt <= '2013-03-01'  -- Analyst selected Point-in-Time Date
         GROUP BY 1)
GROUP BY 1,2

该数据将用于建模目的,因此合理的 SELECT 速度是可以接受的。

  1. 这种方法对于存储和查询来说是否合理?
    • 个别表是否太大?
  2. 有没有更好的建议方法?
    • 我对进一步分裂的担忧是
      • 由于日期和客户 ID 等不可压缩字段而产生的空间
      • 加入 2-3 个表的速度(我怀疑内部连接可能使用很少的资源。)

请原谅我对这件事的无知。我通常使用不会长期存在的大型表(我是一名专业的数据分析师),或者我为长期数据收集构建的表仅包含少数列。

4

2 回答 2

2

160 列、稀疏填充的表的宽度不一定是不正确的物理实现(在 3NF 中标准化或略微去标准化)。我还看到了将不经常访问的属性移动到文档表的情况。如果您选择在您的物理实现中实现后者,那么每个表共享相同的主索引将符合您的最大利益。这允许将这些表(60 个属性和 100 个属性)连接到 Teradata 上的 AMP 本地。

如果对表的访问也将包括该add_dt列,您可能希望在该列上创建一个分区主索引add_dt当列包含在查询的 WHERE 子句中时,这将允许优化器消除扫描其他分区。另一种选择是测试列上按值排序的二级索引add_dt的行为。

于 2013-09-17T19:00:52.370 回答
2

除了 Rob 的评论:

您当前的 PI/分区是什么?

目前的表现是否不尽如人意?

除了时间点之外,分析师如何访问任何其他常见条件?

根据您的需要,(prev_dt,add_dt)可能比单个 add_dt 更好。加载的开销更大,但查询可能像 prev_dt 和 end_dt 之间的 date ... 一样简单。

(cus_id)、(add_dt) 上的连接索引也可能会有所帮助。

您可以用 RANK 替换 MAX(子查询)(MAX 通常较慢,仅当 cus_id 为 PI RANK 时可能更糟):

SELECT *
FROM db1.demo_test 
QUALIFY 
  RANK() OVER (PARTITION BY cus_id ORDER BY add_dt DESC) = 1

在 TD14 中,您可以将单个表拆分为列分区表的两个行容器。

...

于 2013-09-17T19:20:44.743 回答