【发布时间】:2011-06-02 19:41:51
【问题描述】:
想象一下 PostgreSQL 9.0 上具有以下结构的表:
create table raw_fact_table (text varchar(1000));
为了简单起见,我只提到一个文本列,实际上它有十几个。该表有 100 亿行,每列有很多重复项。该表是使用 COPY FROM 从平面文件 (csv) 创建的。
为了提高性能,我想转换为以下星型架构:
create table dimension_table (id int, text varchar(1000));
然后事实表将被替换为如下的事实表:
create table fact_table (dimension_table_id int);
我目前的方法基本上是运行以下查询来创建维度表:
Create table dimension_table (id int, text varchar(1000), primary key(id));
然后创建填充我使用的维度表:
insert into dimension_table (select null, text from raw_fact_table group by text);
之后我需要运行以下查询:
select id into fact_table from dimension inner join raw_fact_table on (dimension.text = raw_fact_table.text);
想象一下通过多次比较所有字符串和所有其他字符串得到的可怕性能。
在 MySQL 上,我可以在 COPY FROM 期间运行存储过程。这可以创建字符串的散列,并且所有后续字符串比较都在散列而不是长原始字符串上完成。这在 PostgreSQL 上似乎是不可能的,那我该怎么办?
示例数据将是一个包含类似内容的 CSV 文件(我也在整数和双精度数周围使用引号):
"lots and lots of text";"3";"1";"2.4";"lots of text";"blabla"
"sometext";"30";"10";"1.0";"lots of text";"blabla"
"somemoretext";"30";"10";"1.0";"lots of text";"fooooooo"
【问题讨论】:
-
这似乎需要多长时间?您预计需要多长时间?
-
我从未使用提到的数据量完成它。但是在 1500 万行上,这需要几个小时。我已经研究了所有标准的服务器优化内容(work_mem 等),所以我采用了不同的方法来获得相同的结果。
-
我已编辑问题以包含示例数据。
标签: postgresql normalization etl star-schema fact-table