【发布时间】:2019-11-19 19:33:01
【问题描述】:
我在 Postgresql 中有两个简单的表,第一个有 170 万 行
CREATE TABLE f_occ(
id_data integer ,
dur integer
);
第二个表有 365 行
CREATE TABLE d_data(
id_data serial ,
full_data date ,
month SMALLINT ,
);
为了优化两个表之间的连接,我尝试在 id_data 上创建哈希索引,但这完全被忽略了。为什么会发生这种情况,如何优化查询?当我在表 d_data 的 where 中插入条件时也会发生这种情况。
CREATE INDEX f_occ_id_data ON public.f_occ USING hash (id_data)
EXPLAIN ANALYZE
SELECT d.month, s.dur
FROM d_data d, f_occ s
WHERE d.id_data = s.id_data;
"Hash Join (cost=10.21..34133.23 rows=1705429 width=6) (actual time=1.479..9158.424 rows=1705429 loops=1)"
" Hash Cond: (s.id_data = d.id_data)"
" -> Seq Scan on f_occ s (cost=0.00..29594.29 rows=1705429 width=8) (actual time=0.096..2992.577 rows=1705429 loops=1)"
" -> Hash (cost=5.65..5.65 rows=365 width=6) (actual time=1.352..1.353 rows=365 loops=1)"
" Buckets: 1024 Batches: 1 Memory Usage: 23kB"
" -> Seq Scan on d_data d (cost=0.00..5.65 rows=365 width=6) (actual time=0.030..0.656 rows=365 loops=1)"
"Planning Time: 0.919 ms"
"Execution Time 11727.436 ms"
【问题讨论】:
-
连接不会减少来自
f_occ的行数,因此对该表的表进行 Seq Scan 是有意义的(毕竟,您正在从该表中检索所有行)。如果只有来自f_occ的一小部分行将从连接中返回,则可能会使用该索引。 -
但如果我尝试插入 d.month = 1 之类的 where 条件,则索引将继续被忽略,该索引仅在我对 full_data 设置条件的情况下使用,例如 d.full_data = '2017-02-02'
-
那么 where 条件没有删除足够的行以使索引有用
标签: sql postgresql query-optimization data-warehouse query-performance