如何在postgresql上执行快速连接

时间:2016-03-06 15:28:24

标签: performance postgresql

在ubuntu-15.10上使用postgres-9.4

在索引列上的两个表上执行连接并获取Seq Scan

a:〜{700万行,包含char()&varchar()&float,在date char(11)上具有聚集的b-tree索引。每个日期1~2500行。

b:~6k行,包含2个col date char(11) and feature float[]date char(11)上也有聚集的b-tree索引。每个日期只有1条记录。

我有以下问题,cols中的select太多太丑了,所以我简短了:

SELECT
  6 regexp_split_to_array(a.char_cols),
  ARRAY[ a.all_float] || b.feature
FROM
  a JOIN b ON
a.date = b.date;

需要约50000毫秒并使用EXPLAIN ANALYZE VERBOSE我有以下结果:

QUERY PLAN
-----------------------------------------------------------------------------
 Hash Join  (cost=501.67..790703.48 rows=7154354 width=856) (actual time=3.216..49223.885 rows=7154589 loops=1)
   Output: A_LOT_MESS
   Hash Cond: (a.date = b.date)
   ->  Seq Scan on public.a  (cost=0.00..521913.54 rows=7154354 width=440) (actual time=0.001..967.771 rows=7154589 loops=1)
     Output: EVERY_COLS_OF_A
   ->  Hash  (cost=424.63..424.63 rows=6163 width=428) (actual time=3.157..3.157 rows=6163 loops=1)
     Output: b.feature, b.date
     Buckets: 1024  Batches: 1  Memory Usage: 2769kB
     ->  Seq Scan on public.b  (cost=0.00..424.63 rows=6163 width=428) (actual time=0.003..1.156 rows=6163 loops=1)
           Output: b.feature, b.date
 Planning time: 1.041 ms
 Execution time: 49396.419 ms
(12 rows)

我尝试了PostgreSQL query runs faster with index scan, but engine chooses hash join

的建议

set random_page_cost = 2set work_mem = '2048MB'都不会产生任何影响:计划和时间保持不变。

我看到一些文章说位图索引扫描可以做得更好,但我不知道如何创建这样的索引:似乎postgres决定是否应该在查询时生成它。

其他信息:

关于资源使用情况:

查询只需要一个逻辑核心就可以工作,并且我有足够的内存(32GiB,当数据库大小<6GiB时)

1 个答案:

答案 0 :(得分:3)

此查询不会使用索引,因为查询正在使用public.a的所有7M行。只有当你制作一个限制性更强的过滤器,只需public.a中只有一小部分行来运行查询时,你就会看到索引被使用了。

如果查看查询的实际运行时间,您会注意到顺序扫描时间不到1秒(准确地说是967.771 ms),而连接需要大约48秒。