我有一次需要在 25M 行上进行 25M 行的内部连接。盒子是Alienware area 51,4核25GB内存和SATA驱动(非系统盘)。到目前为止,它已经花费了 22 小时。我做了 btree 索引 ID (bigint) 列,这两个表都在进行连接。有小费吗?你觉得我要等多久?
EXPLAIN SELECT
public.products_by_location_mv.id,
public.products_by_location_mv."data_object.unique_id",
public.products_by_location_mv.location AS outline,
public.products_by_location_mv.elevation_ft,
public.products_by_location_mv."geo_product.geo_product_id" AS pid,
public.products_by_location_mv.cntry_name,
public.products_by_location_mv.product_name,
public.products_by_location_mv.product_type,
public.products_by_location_mv.product_producer,
public.products_by_location_mv.product_size,
public.products_by_location_mv.do_location,
public.products_by_location_mv.product_location,
public.obj4.uid AS oid,
public.obj4.size_bytes,
public.obj4.object_date,
public.obj4.description,
public.obj4.location AS path
INTO
public.inventory0
FROM
public.obj4
INNER JOIN
public.products_by_location_mv
ON
(
public.obj4.id = public.products_by_location_mv.id) ;
"Hash Join (cost=3825983.03..12908235.27 rows=24202368 width=1356)"
" Hash Cond: (products_by_location_mv.id = obj4.id)"
" -> Seq Scan on products_by_location_mv (cost=0.00..1457298.68 rows=24202368 width=721)"
" -> Hash (cost=1414691.68..1414691.68 rows=25507868 width=643)"
" -> Seq Scan on obj4 (cost=0.00..1414691.68 rows=25507868 width=643)"
虽然我很难理解这种查询的动机,但你不能指望任何效率,因为查询结果不适合主内存。如果您希望以某种方式存储结果,唯一的方法是通过 COPY 命令(http://www.postgresql.org/docs/9.2/static/sql-copy.html)。COPY 的优点是,一旦从查询中检索到一行,它就会直接进入辅助存储。这样,您实际上有机会在几个小时后完成查询。然后,如果需要,您可以再次使用 COPY 将这些结果加载到另一个数据库表中。
就像我说的,它是一次性操作(我需要它对一些大数据进行一次性清理,而且它永远不像 ACID 时代的东西那样合规)。
也就是说,我确实尝试过使用更少的列,并且性能非常好。37 分钟。(快速 VACUUM 也可能有所帮助)。
见下文: