Ubuntu Node.js 日志中的数据库查询优化提示
一 日志采集与结构化
- 使用成熟的日志库(如 Winston、Pino、Bunyan)统一格式,输出 JSON,便于检索与聚合。
- 合理设置日志级别(如 DEBUG/INFO/WARN/ERROR),生产环境避免过多 DEBUG。
- 开启日志轮转:应用侧可用 winston-daily-rotate-file,系统侧用 logrotate 管理磁盘占用。
- 将日志接入集中式平台(如 ELK)以便跨实例分析与可视化。
- 在日志中记录关键字段:query、params、durationMs、rows、route、userId/host、timestamp,为后续慢查询定位提供依据。
二 从日志发现慢查询
- 在应用日志中识别高耗时样本:例如通过 grep/awk 筛选超过阈值的请求(如 >1000ms),并关联到具体 SQL/参数/路由。
- 将慢查询落入独立日志或指标,便于长期跟踪与告警。
- 在数据库侧开启并分析 慢查询日志,对可疑语句使用 EXPLAIN ANALYZE 验证执行计划与代价。
- 使用系统视图监控连接与活跃语句(如 PostgreSQL:pg_stat_activity),定位阻塞与长事务。
三 SQL 与索引层面的优化要点
- 避免 **SELECT ***,仅返回必要列;减少网络与内存开销。
- 为高频 WHERE/JOIN/ORDER BY 列建立合适的 索引,必要时使用 复合索引;注意索引维护成本。
- 优化 JOIN 与子查询,优先转换为 JOIN 或使用临时表,减少不必要的数据扫描。
- 解决 N+1 查询(如 ORM 场景),采用 预加载/批量加载 降低往返次数。
- 大数据量列表使用 分页/游标 分页,避免一次性拉取过多数据。
- 对热点数据引入 缓存(Redis/Memcached),设置合理 TTL,减少数据库压力。
四 连接与代码执行优化
- 使用 连接池 复用连接,合理设置 max/min、idleTimeoutMillis、connectionTimeoutMillis,避免连接风暴与超时。
- 全程使用 异步 非阻塞 I/O,避免 同步 文件/数据库操作阻塞事件循环。
- 合并多次写操作为 批量插入/更新,降低往返次数与锁竞争。
- 优化数据结构与算法,减少不必要的中间转换与内存拷贝。
五 监控维护与持续优化
- 建立 Prometheus + Grafana 监控面板,跟踪 P95/P99 延迟、QPS、错误率、连接数、缓存命中率 等核心指标。
- 定期执行数据库维护:更新统计信息、重建/重组索引、清理碎片,保持执行计划稳定。
- 结合 日志 + APM(如 New Relic) 做端到端链路追踪,定位跨服务瓶颈。
- 对大表考虑 分区/分片 与读写分离,提升可扩展性与查询性能。