为什么 PostgreSQL 在 Merge Join 场景中不使用索引?
Why isn't PostgreSQL using an index in a Merge Join scenario?
explain select count(1) from tab1_201502 t1, tab2_201502 t2
where t1.serv_no=t2.serv_no
and t1.PC_LOGIN_COUNT1 >5
and t1.FET_WZ_FEE < 80
and t2.ALL_FLOW_2G<50;
QUERY PLAN
----------------------------------------------------------------------
Aggregate (cost=4358706.25..4358706.26 rows=1 width=0)
-> Merge Join (cost=4339930.99..4358703.30 rows=1179 width=0)
Merge Cond: ((t1.serv_no)::text = (t2.serv_no)::text)
-> Index Scan using tab1_201502_serv_no_idx on tab1_201502 t1
(cost=0.56..6239071.57 rows=263219 width=12)
Filter: ((pc_login_count1 > 5::numeric)
AND (fet_wz_fee < 80::numeric))
-> Sort (cost=4339914.76..4340306.63 rows=156747 width=12)
Sort Key: t2.serv_no
-> Seq Scan on tab2_201502 t2
(cost=0.00..4326389.00 rows=156747 width=12)
Filter: (all_flow_2g < 50::numeric)
所有表都在 serv_no
上建立了索引。
为什么 PostgreSQL 忽略 tab2_201502
索引进行扫描?
这是您的查询:
select count(1)
from tab1_201502 t1 join
tab2_201502 t2
on t1.serv_no = t2.serv_no
where t1.PC_LOGIN_COUNT1 > 5 and t1.FET_WZ_FEE < 80 and t2.ALL_FLOW_2G < 50;
Postgres 决定通过 where
子句过滤比执行 join
.
更重要
我建议为此查询尝试两组索引。它们是:tab2_201502(ALL_FLOW_2G, serv_no)
和 tab1_201502(serv_no, PC_LOGIN_COUNT1, FET_WZ_FEE)
.
第二对是:tab1_201502(PC_LOGIN_COUNT1, FET_WZ_FEE, serv_no)
和 tab2_201502(serv_no, ALL_FLOW_2G)
。
哪个效果更好取决于 table 是 join
的驱动 table。
explain select count(1) from tab1_201502 t1, tab2_201502 t2
where t1.serv_no=t2.serv_no
and t1.PC_LOGIN_COUNT1 >5
and t1.FET_WZ_FEE < 80
and t2.ALL_FLOW_2G<50;
QUERY PLAN
----------------------------------------------------------------------
Aggregate (cost=4358706.25..4358706.26 rows=1 width=0)
-> Merge Join (cost=4339930.99..4358703.30 rows=1179 width=0)
Merge Cond: ((t1.serv_no)::text = (t2.serv_no)::text)
-> Index Scan using tab1_201502_serv_no_idx on tab1_201502 t1
(cost=0.56..6239071.57 rows=263219 width=12)
Filter: ((pc_login_count1 > 5::numeric)
AND (fet_wz_fee < 80::numeric))
-> Sort (cost=4339914.76..4340306.63 rows=156747 width=12)
Sort Key: t2.serv_no
-> Seq Scan on tab2_201502 t2
(cost=0.00..4326389.00 rows=156747 width=12)
Filter: (all_flow_2g < 50::numeric)
所有表都在 serv_no
上建立了索引。
为什么 PostgreSQL 忽略 tab2_201502
索引进行扫描?
这是您的查询:
select count(1)
from tab1_201502 t1 join
tab2_201502 t2
on t1.serv_no = t2.serv_no
where t1.PC_LOGIN_COUNT1 > 5 and t1.FET_WZ_FEE < 80 and t2.ALL_FLOW_2G < 50;
Postgres 决定通过 where
子句过滤比执行 join
.
我建议为此查询尝试两组索引。它们是:tab2_201502(ALL_FLOW_2G, serv_no)
和 tab1_201502(serv_no, PC_LOGIN_COUNT1, FET_WZ_FEE)
.
第二对是:tab1_201502(PC_LOGIN_COUNT1, FET_WZ_FEE, serv_no)
和 tab2_201502(serv_no, ALL_FLOW_2G)
。
哪个效果更好取决于 table 是 join
的驱动 table。