在修改数据库前先找出代价高的请求
从一次用户行为开始:类别加载、文章搜索、加入购物车或提交订单。记录其路由、查询次数、数据库耗时、返回行数和请求总时长。页面变慢也可能是因为应用代码或其他依赖项阻塞,因此不要仅凭页面加载时间来判断。
查询计划是数据库在表、索引、连接、排序和聚合之间的执行路径。在 PostgreSQL 中,EXPLAIN 会显示该路径。EXPLAIN ANALYZE 会执行语句并报告实际行数和时间,因此应对安全的、具代表性的查询使用它。估算行数与实际行数差距很大是调查统计信息或条件的理由,而不是自动添加索引的唯一依据。
将候选查询与具体路由和结果关联,以免仅凭仪表盘报告掩盖结账变慢的事实。
记录变更前的时间指标和可比流量,但不要记录客户标识、令牌或与银行卡相关的值。
为实际使用的访问路径设计索引
索引是一种维护的结构,可帮助定位行或按顺序返回它们;它并非万能的性能开关。首先从重要查询的过滤条件、连接键和排序顺序入手,然后在执行计划中验证拟议的索引。PostgreSQL 记录指出,匹配的 B-tree 索引在某些情况下可以满足 ORDER BY 而无需额外排序,尤其是在小 LIMIT 时。
索引增加存储占用并增加写入开销,因为插入、更新和删除操作需要维护索引。对于需要扫描表很大比例的查询,顺序扫描加显式排序可能更快。在类似生产的数据上测试,只有当收益能证明其成本合理时才保留索引。
使用查询的实际过滤条件和 ORDER BY,包括在界面需要稳定顺序时添加确定性的决胜字段。
检查索引是否被使用以及其在写入时的成本;随着数据和流量变化要重新评估。
让分页既稳定又可承受
基于页码的分页通常使用 LIMIT 与 OFFSET。始终指定可预测的排序。PostgreSQL 警告说,如果没有 ORDER BY,LIMIT 可能返回不可预测的子集;不同的 LIMIT 或 OFFSET 值可能产生不一致的结果,因为优化器可能会选择不同的执行计划。
大偏移量需要审查,因为被跳过的行仍然需要被计算。对于深度目录、订单历史或档案浏览,考虑使用游标或键集分页(keyset pagination):请求在上次看到的稳定排序值和唯一决胜字段之后的行。在更改界面之前,先定义新记录或删除记录如何呈现。
返回最小可用的页大小,而不是未限制的结果集。
决定界面是否确实需要在每次请求时返回精确的总数。
缓存读取工作但不返回错误响应
缓存复用先前的结果,而不是每次都从数据库重建。对于公共的、可重复的页面和带版本号的资源,应从 HTTP 层开始,因为命中缓存可以避免应用和数据库的工作。web.dev 建议对带版本的 URL 使用长期缓存;改变 URL 是实用的失效机制。
缓存策略是一个正确性决策。共享缓存可能会在多个用户间复用同一响应,因此除非已为该范围设计并测试,否则不要共享账户、购物车、价格或授权相关的输出。Cache-Control private 将重用限制在浏览器缓存,而 no-store 指示缓存不保留响应。
将公共目录或文章输出与会话特定、地域特定和权限敏感的输出分开。
定义谁可以看到过期值、可见多长时间,以及失效或重新验证的路径。
保护连接容量,而不是简单地提高上限
连接是指到数据库的活跃客户端会话。工作进程、定时任务、预览或重试可能会耗尽连接槽位,即便单个查询看起来可接受。PostgreSQL 的 max_connections 控制并发连接数,在服务器启动时设置,增大该值会分配更多资源,包括共享内存。没有工作负载模型地提高该值可能只是把故障转移到别处。
为 Web 工作进程、后台任务、管理操作和副本设定统一的连接预算。在适合的场景使用有界连接池,为恢复保留余量,并设置超时以避免滞留工作无限期等待。安全的连接数取决于引擎、内存、查询类型和服务商限制;请与运维确认。
包括 Web 进程、队列、定时任务、迁移、报表工具和部署作业。
限制并发并使用退避机制,以免故障导致连接需求成倍增长。
在上下文与隐私控制下观察查询成本
按总体影响对数据库工作进行排序,而不是按某次慢查询样本。被调用数千次的中等慢查询可能比罕见的慢报表更重要。PostgreSQL 的 pg_stat_statements 聚合计划和执行数据,包括调用次数、总/平均执行时间、行数和缓冲区活动。它需要服务器配置并在添加或移除时重启;计划跟踪可能增加开销。
将查询组与路由、发布版本和时间窗口关联。OpenTelemetry 建议只有在对文字(literals)进行清理替换后才默认收集查询文本,并使用低基数的查询摘要进行分组。这有助于负责人在不导出客户数据或为每个值创建标签的情况下查看趋势。
检查时长、总耗时、调用次数、错误、连接和行数;每项都能揭示不同的故障模式。
使用参数化查询,并在追踪或日志离开应用前确认文字常量已被移除。
将数据库变更作为可回滚的可靠性工作发布
将索引、重写、缓存策略、连接池设置或模式变更视为生产变更,需指定负责人、成功度量和回滚策略。在具代表性的环境中验证,将变更先发布到小范围,并监控受影响的旅程。如果变更返回错误、缺失、重复或过期的数据,性能提升并不意味着成功。
模式变更需要谨慎,因为应用版本可能并存。Google Cloud 的指南描述了兼容性顺序:先发布能够处理旧/新模式的应用,随后变更模式,再发布使用新模式的功能。这样可以保留应用回滚路径。锁和在线变更行为因数据库引擎和托管服务而异;对于高流量或与支付相关的系统,应获得合格的评审。
明确命名路由、性能与正确性信号,以及停止发布的阈值。
在扩大范围前先在受控小范围内验证性能与正确性;在非事件时练习回退路径。
