Postgres10高性能开发(4)控制解释计划

控制解释计划

参数控制

参数默认值说明
enable_bitmapscanon启用或禁用位图索引扫描
enable_gathermergeon启用或禁用收集合并,并发查询时会出现收集合并
enable_hashaggon启用或禁用HashAggregate
enable_hashjoinon启用或禁用Hash Join
enable_indexscanon启用或禁用索引扫描
enable_indexonlyscanon启用或禁用Index only scan
enable_materialon启用或禁用物化中间结果,不建议关闭
enable_mergejoinon启用或禁用Merge Join
enable_nestloopon启用或禁用Nested Loop
enable_seqscanon启用或禁用全表扫描
enable_sorton启用或禁用显示排序
enable_tidscanon启用或禁用行ID扫描

统计

  • 建立多列统计
  • 控制统计采样范围,默认为100,范围0到 10000。值越大,采样约准确,但ANALYZE耗时越长
    • 全局控制:default_statistics_target变量
    • 具体字段:ALTER TABLE inv_t_invoice ALTER cl_id SET STATISTICS 200;
  • 默认ANALYZE会不定期自动执行。但在大量数据修改后,可能需要手动ANALYZE生成新的统计值

索引

  • 建立索引
  • 建立部分索引,除去索引效果不大的值

Join

当查询只涉及到2-3张表联表时,规划器可以生成较优的表连接顺序。规划器分析时间随着表的增多指数级增加。如果表太多,规划器将使用遗传概率搜索,但不一定能找到最佳表连接顺序。

因此需要通过Join指定表连接顺序

只有FULL JOIN完全指定了连接顺序

另外外连接优先级低于内连接

SELECT * FROM a LEFT JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id);

上面的SQL指定先连接B和C,然后再和A连接

可通过调整Postgres运行时参数改变规划器行为

  • from_collapse_limit:from中的表个数不大于from_collapse_limit时,将使用from中定义的顺序。默认为8
  • join_collapse_limit:join(不包含FULL JOIN)中的表个数不大于from_collapse_limit时,将使用from中定义的顺序。默认为等于from_collapse_limit

如果要强制指定规划器使用SQL的连接顺序,可以将from_collapse_limit,join_collapse_limit 设置为1,防止规划器重新排序

默认情况下

explain select * from inv_t_invoice i join inv_t_invoice_detail d on i.cl_id = d.cl_invoice_id
join  inv_t_invoice_cash c on i.cl_id = c.cl_invoice_id;

#Result
Hash Join  (cost=531.63..8435.58 rows=15579 width=3086)
  Hash Cond: ((i.cl_id)::text = (d.cl_invoice_id)::text)
  ->  Nested Loop  (cost=0.29..7545.20 rows=14881 width=2860)
        ->  Seq Scan on inv_t_invoice i  (cost=0.00..2278.72 rows=8972 width=2385)
        ->  Index Scan using idx_invoice_cash_invoice_id on inv_t_invoice_cash c  (cost=0.29..0.57 rows=2 width=475)
              Index Cond: ((cl_invoice_id)::text = (i.cl_id)::text)
  ->  Hash  (cost=413.93..413.93 rows=9393 width=226)
        ->  Seq Scan on inv_t_invoice_detail d  (cost=0.00..413.93 rows=9393 width=226)

注意:规划器修改了默认联表顺序,先连接inv_t_invoice和inv_t_invoice_cash,然后才是inv_t_invoice_detail

set join_collapse_limit=2;

explain select * from inv_t_invoice i join inv_t_invoice_detail d on i.cl_id = d.cl_invoice_id
join  inv_t_invoice_cash c on i.cl_id = c.cl_invoice_id;

Nested Loop  (cost=531.63..8483.11 rows=15579 width=3086)
  Join Filter: ((i.cl_id)::text = (c.cl_invoice_id)::text)
  ->  Hash Join  (cost=531.34..3026.53 rows=9393 width=2611)
        Hash Cond: ((i.cl_id)::text = (d.cl_invoice_id)::text)
        ->  Seq Scan on inv_t_invoice i  (cost=0.00..2278.72 rows=8972 width=2385)
        ->  Hash  (cost=413.93..413.93 rows=9393 width=226)
              ->  Seq Scan on inv_t_invoice_detail d  (cost=0.00..413.93 rows=9393 width=226)
  ->  Index Scan using idx_invoice_cash_invoice_id on inv_t_invoice_cash c  (cost=0.29..0.56 rows=2 width=475)
        Index Cond: ((cl_invoice_id)::text = (d.cl_invoice_id)::text)

通过设置join_collapse_limit小于3,成功让规划器按inv_t_invoice、inv_t_invoice_detail、inv_t_invoice_cash的默认顺序联表

  • 0
    点赞
  • 2
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

supermancoke

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值