在PostgreSQL + PostGIS上有效插入数百万行,转换数据并处理数据的方法

时间:2013-01-21 14:28:20

标签: postgresql optimization loading postgis

我想要用于以后用户搜索的大量数据。 目前我拥有2亿资源(约50GB)。对于每个人,我有纬度+经度。目标是创建空间索引以便能够对其进行空间查询。 因此,计划是使用PostgreSQL + PostGIS。

我的数据在CSV文件中。我试图使用自定义函数不插入重复项,但经过几天的处理我放弃了。我找到了一种在数据库中快速加载的方法:使用COPY只需不到2个小时。

然后,我需要在几何格式上转换纬度+经度。为此,我只需要这样做:

ST_SetSRID(ST_MakePoint(longi::double precision,lat::double precision),4326))

经过一番检查后,我看到了2亿,我有5000万点。因此,我认为最好的方法是使用一个表“TABLE_POINTS”来存储所有的点,一个表“TABLE_RESOURCES”将用point_key存储资源。

所以我需要从临时表“TABLE_TEMP”中填写“TABLE_POINTS”和“TABLE_RESOURCES”,而不是保留重复项。

对于“POINTS”我做了:

INSERT INTO TABLE_POINTS (point)
SELECT DISTINCT ST_SetSRID(ST_MakePoint(longi::double precision,lat::double precision),4326))
FROM TABLE_RESOURCES

我不记得花了多少时间,但我认为这是几个小时的问题。

然后,为了填写“资源”,我尝试了:

INSERT INTO TABLE_RESOURCES (...,point_key)
SELECT DISTINCT ...,point_key
FROM TABLE_TEMP, TABLE_POINTS
WHERE ST_SetSRID(ST_MakePoint(longi::double precision,lat::double precision),4326) = point;

但又需要几天时间,并且无法查看查询的距离......

同样重要的是,资源数量将继续增长,目前应该是白天增加的100K,因此应优化存储以保持对数据的快速访问。

因此,如果您对存储的加载或优化有任何想法,欢迎您。

2 个答案:

答案 0 :(得分:0)

首先考虑优化postgres(即google postgres unlogged,wal和fsync选项),第二,你真的需要积分才能独一无二吗?也许只有一个表与资源和点组合,不担心重复点,因为它似乎你的重复查找可能会很慢。

答案 1 :(得分:0)

要使DISTINCT高效工作,您需要在那些要消除重复项的列上建立数据库索引(例如,在纬度/经度列上,甚至在所有列的集合上)

首先将所有数据插入到临时表中,然后CREATE INDEX(这通常比预先创建索引更快,因为在插入期间维护它是昂贵的),并且之后只执行INSERT INTO ... SELECT DISTINCT

EXPLAIN <your query>可以告诉您SELECT DISTINCT现在是否使用索引。