数据库 PostgreSQL 的执行计划, 我想怎么看是否有回表

chengsukai · 2022年07月26日 · 最后由 hjiangwen 回复于 2022年08月04日 · 363 次阅读

测试环境

环境 版本
Postgres v14
DataGrip 2022.1.5

测试脚本

https://chengsukai.oss-cn-hangzhou.aliyuncs.com/blog/d102_seat_center.sql

测试结果

而且创建了索引之后, 他的执行时间也非常高, 希望得到大家的指点

只要触发了索引外的字段,就需要回表来显示数据的吧

查询条件太多了,索引很难利用好,另外你好多条件都是字符串,为什么不用 int

因为是老项目, 修改比较麻烦

这就是回表的。因为你有大量索引外的字段。如果只查索引的叫 index only scan 。

其实是不是回表无所谓。因为业务拼装的 SQL 可能性很多。一般建立索引是快速缩小范围,然后再回表查。你可以用 “哪些字段能让你快速过滤掉大量无关数据” 的原则来建立索引。

“哪些字段能让你快速过滤掉大量无关数据”

换句话说,也就是这个查询条件的区分度足够高 (selectivity)。带有 unique index 的 column 区分度最高,因为表里每条记录的值都不一样,即使是有几百万行的表,通过 B Tree 索引,只需要几次 IO 就能找到对应的记录。高区分度 => 查询范围小 => 快 🚀

通过 pg_stats 看各个字段的值的分布情况。比如一个枚举字段 status,各个值的出现频率是 ({done: 0.9, failed: 0.08, pending: 0.02}),那 status = pending 就是一个高区分度的查询条件,因为它能过滤掉 99.8% 的数据。

你甚至可以给一个高区分度的查询条件建一个partial index,进一步减少查询范围

需要 登录 后方可回复, 如果你还没有账号请 注册新账号