不靠谱——SELECT 1 测的是数据库服务端响应时间,含连接建立、SQL解析、权限校验等环节;真测网络 RTT 应用 ping 或 nc;仅适合健康检查或轻量连通性验证。
用 SELECT 1 测延迟靠谱吗?
不靠谱——它测的不是网络延迟,而是数据库服务端响应时间,中间夹着连接建立、sql解析、权限校验、执行计划生成等环节。真想看网络 rtt,得用 ping 或 telnet;想快速验证 db 是否“活着且能走通 sql 路径”,select 1 才有意义。
常见错误现象:SELECT 1 耗时 200ms,就以为是网络卡,结果发现是 DB 正在做 checkpoint 或连接池没复用;或者压根没连上,却因为连接超时长(比如 30s),误判为“慢”而非“不通”。
- 使用场景:适合健康检查(如 Kubernetes
livenessProbe)、CI/CD 中轻量级连通性确认 - 别用它替代
time curl -I http://db-host:port/health或time nc -zv db-host 5432 - PostgreSQL / MySQL / SQL Server 都支持,但 SQLite 不行(无服务端)
mysql 和 psql 执行 SELECT 1 的差异点
命令行工具行为不同,直接影响你看到的“耗时”是否包含连接开销:
-
mysql -h host -u user -p -e "SELECT 1":每次都会新建 TCP 连接,耗时含 TCP 握手 + 认证,适合模拟首次连接场景 -
psql -h host -U user -c "SELECT 1":默认启用连接复用(如果前序会话未退出),可能掩盖真实建连延迟 - MySQL 的
--skip-tee和psql的\set QUIET on可减少输出干扰,让time测得更准 - 注意:MySQL 8.0+ 默认开启 caching_sha2_password 插件,首次认证比 mysql_native_password 慢 50–100ms,这不是网络问题
为什么加 /*+ MAX_EXECUTION_TIME(1000) */ 反而让测试更稳?
防止 SELECT 1 卡死在锁或长事务里——虽然它本身不写也不查表,但在某些引擎(如 MySQL 的 InnoDB)中,仍需获取轻量级元数据锁或 MVCC 快照。一旦上游有大事务未提交,SELECT 1 可能被阻塞数秒。
- MySQL 可加 hint:
SELECT /*+ MAX_EXECUTION_TIME(1000) */ 1,超 1s 自动中断 - PostgreSQL 用
SET statement_timeout = '1s'; SELECT 1;,但要注意连接级设置会污染后续语句 - 不设超时的后果:K8s 探针失败、监控告警误触发、自动化脚本 hang 住
- 这个超时值必须小于你的探测间隔(比如探针周期是 10s,timeout 就不能设成 10s)
真正要测网络层延迟,该用哪条命令?
绕过数据库协议栈,直击 TCP 层。否则你永远分不清是网线松了,还是 pg_hba.conf 写错了。
- 基础验证:
nc -zv db-host 5432(PostgreSQL)或nc -zv db-host 3306(MySQL),看是否能完成 TCP 握手 - 带时间戳测 RTT:
time printf "" | nc -w1 db-host 5432 2>&1 | grep real(注意-w1是连接超时,非传输超时) - 避免 DNS 干扰:直接用 IP,比如
nc -zv 10.20.30.40 5432;若成功但域名失败,就是 DNS 解析问题 - 别用
ping测 DB 端口:ICMP 和 TCP 完全不同路径,防火墙常放行 ICMP 但封 TCP
SELECT 1 前如果要等连接池分配空闲连接,那测出来的根本不是 DB 响应,而是连接池的排队时间。










