假设在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"