EXPLAIN (ANALYZE) SELECT * FROM orders WHERE user_id = 100;
EXPLAIN SELECT * FROM orders WHERE user_id = '100';

orders 表上 idx_orders_user_id 明明在,EXPLAIN 里却始终是 Seq Scan,条件只有一个等值比较,查询稳定在 1.2 秒。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。

原因不复杂,user_id 是 varchar 类型,SQL 里却写数字常量,PG 只能把整列隐式转成 numeric 再比较,索引和统计信息都用不上,改 SQL 比改列类型快。

「PG 索引失效类型转换」确认了原因之后,改动尽量只碰那一处,顺手改的东西后面最容易出问题。动手前把原文件复制一份带时间戳,出问题立刻换回去,比现场分析快得多。

一次只改一处,改完立刻验证,几个改动叠在一起,出问题就说不清是谁导致的。先做最小复现,能稳定跑出来的问题,排查成本会低一个数量级。

处理上按这个顺序:先看 EXPLAIN 输出里有没有对参与比较的列做 cast;把常量改成与列同类型并带上单引号,再跑一次对比计划;长期方案是把列类型和调用方一起改对,别只在 SQL 里绕。

改完只确认一件事:改成字符串常量后计划变成 Index Scan,扫描行数从四十万降到个位数。

作者 9823189