在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 = 2
和set work_mem = '2048MB'
都不会产生任何影响:计划和时间保持不变。
我看到一些文章说位图索引扫描可以做得更好,但我不知道如何创建这样的索引:似乎postgres决定是否应该在查询时生成它。
其他信息:
关于资源使用情况:
查询只需要一个逻辑核心就可以工作,并且我有足够的内存(32GiB,当数据库大小<6GiB时)
答案 0 :(得分:3)
此查询不会使用索引,因为查询正在使用public.a
的所有7M行。只有当你制作一个限制性更强的过滤器,只需public.a
中只有一小部分行来运行查询时,你就会看到索引被使用了。
如果查看查询的实际运行时间,您会注意到顺序扫描时间不到1秒(准确地说是967.771 ms),而连接需要大约48秒。