连接池那篇的后续
上次把空闲回收改短、定时任务的连接也还回去之后,5 秒超时没再出现。我以为这件事结束了。上周四晚上又有一批慢,不过只有 1 秒出头,而且只打在 GET /reports/monthly 上。
等待连接的时间这次是正常的,慢在查询本身。月报 SQL 扫了 invoices 全表,条件是月份字符串拼接,索引用不上。连接池改好之后,排队消失了,原来被超时挡住的慢查询就露出来了。之前不是没有这条慢查询,是请求在拿到连接之前就已经被网关掐掉,慢查询日志里看不到。
EXPLAIN 里实际走的是 created_at 上的索引,但月份是按上海时区切的,条件写成了 to_char(created_at, 'YYYY-MM') = $1,函数套在列上,索引失效。改成范围:
1 | created_at >= $start AND created_at < $end |
$start 和 $end 在应用里用 Asia/Shanghai 算好再传进去。五月的月报从 1.4 秒降到 70 毫秒左右。这是今天中午在从库上跑的,生产还没发,准备跟明天的窗口一起上。
所以连接池那次只解决了「拿不到连接」。拿到连接之后查询照样可以慢。两件事情长得像,日志不分开的话还会再误判一次。