搞数据库的朋友最近常刷到PG四大神兽吧?别懵,这可不是玄幻网文,是PostgreSQL里大名鼎鼎的四个执行计划节点优化功能——Seq Scan、Index Scan、Nestloop Join、Hash Join,俗称扫全表的穷奇、找索引的饕餮、搭小循环的混沌、玩哈希表的梼杌。很多刚从MySQL转来的运维小白,或者只会写简单SQL的开发新手,没搞懂这些优化节点,要么全表扫卡成PPT,要么索引白建查不快,甚至连PG的查询计划都看不懂。今天咱们就聊透这四个家伙,附真实提效案例,帮你快速入门PG优化。
Seq Scan穷奇为啥这么“慢得离谱”?真的不能碰吗?
很多人一看到PG查询计划里跳出Seq Scan(穷奇),就觉得肯定是慢查询——这可是对PG的误解!Seq Scan是全表顺序扫描节点,适合小表全量查询或者大数据表无筛选条件统计的场景。之前帮朋友优化一个10万行的小订单日志表,之前有人为了全量统计日均访问,硬加了一个索引字段,反而每次查要花0.8秒,后来我让他去掉索引,强制(或者默认就能触发)用Seq Scan穷奇,时间直接降到0.12秒,提效了6.6倍!所以别盲目排斥全表扫描,要看数据量和查询需求。
Index Scan饕餮为啥有时候“帮倒忙”?怎么选合适的索引?
Index Scan(饕餮)是索引查找节点,能快速定位数据,适合带精准筛选或范围查询的场景,但如果索引选得不对,反而会比Seq Scan穷奇慢。比如朋友公司有个500万行的大商品表,之前给价格、库存、上架时间都建了单独索引,但查“上架6个月以上、库存5-10件、价格100-200元的滞销商品”时,PG居然还是选了Seq Scan,每次查2.7秒。后来我建议建一个复合索引(上架时间+库存+价格),调整成Index Only Scan(饕餮的高级版),时间直接降到0.18秒,提效15倍!选索引的时候,要把筛选频率高的字段放前面,尽量用覆盖索引。
Nestloop混沌、Hash Join梼杌怎么搭?连表查速度快10倍?
最后说两个连表查询优化节点——Nestloop Join(混沌)是嵌套循环连接,适合小表驱动大表、大表有精准索引的场景;Hash Join(梼杌)是哈希表连接,适合两个大数据表无小表驱动、筛选条件少的全量连表。上周帮教育公司优化连表查学员成绩的SQL,之前是用200万行的学员表驱动1000万行的成绩表,但成绩表的学员ID没建索引,每次查32秒!后来给成绩表的学员ID建了普通索引,触发Nestloop混沌,时间降到2.1秒;再后来又优化了查询条件,缩小筛选后的学员表到5000行,覆盖成绩查询的必要字段,触发Nestloop+Index Only Scan,时间直接降到0.29秒,提效超100倍!
总之,PG四大神兽没有好坏之分,只有合适不合适的场景。新手可以先从看EXPLAIN ANALYZE执行计划开始,熟悉四个节点的触发条件,然后慢慢调整索引和SQL语句,就能快速提升PG的查询效率。现在就去试试你的第一个PG执行计划吧,有问题欢迎在评论区留言讨论!
标签: PG四大神兽