C++ 与 SQL 性能优化
在保持功能语义、接口约定和数据正确性的前提下,找出并改善有证据支持的性能瓶颈。不要仅凭代码外观猜测慢点,也不要把微基准结果直接当成线上收益。
通用流程
- 确认目标和约束。 从项目与用户描述中识别性能目标、代表性输入、调用频率、延迟或吞吐要求、内存限制,以及并发和部署环境。SQL 优化还要确认数据库类型与版本、表结构、索引、数据规模和参数分布。缺少的关键信息要明确标出,不要自行假定。
- 定位瓶颈。 优先使用已有 profiler、性能记录、慢查询日志或执行计划。区分 CPU、分配与复制、锁等待、I/O、网络、扫描行数和排序等成本;把观察到的证据与推测分开。
- 一次改一个主要因素。 采用范围小、容易审查和回退的修改。先考虑算法复杂度、重复工作、数据访问方式与批处理,再考虑微优化或数据库专用功能。
- 核对正确性与收益。 用相同或足够接近的工作负载对比优化前后表现,并检查结果、边界条件和资源成本。遵守项目现有验证方式及用户授权;没有实测数据时,把收益写成预期,不要声称已经提速。
- 说明结果。 简要记录瓶颈证据、修改点、验证条件与观测结果,以及索引维护、内存、写入开销或复杂度等取舍。
C++ 优化
- 先查看热点路径和目标构建配置,再检查循环中的重复计算、临时对象与内存分配、数据结构复杂度、缓存局部性、锁竞争、系统调用和 I/O。只对证据表明重要的路径做优化。
- 可评估减少不必要的复制或分配、合理预留容量、改善算法复杂度、复用结果、批量处理 I/O,或缩短共享锁的持有时间。选择符合项目语言标准和现有风格的实现。
- 保持对象生命周期与所有权、异常安全、迭代器有效性、并发同步、数值精度和输出顺序等约定。修改浮点计算、并发逻辑或数据结构时,检查其可观察行为是否改变。
- 性能对比应使用与目标场景一致的构建类型、编译器选项和输入规模;避免把调试构建结果用于代表发布性能。注意预热、重复测量和运行环境噪声,并报告测量条件。
- 不为追求速度引入未定义行为、易失效的指针假设、未经证明的无锁结构,或难以维护的复杂缓存。不要仅因局部微基准更快就替换整个实现。
- easy code 原则,尽可能写简单的代码.
- early return 原则,不要用太多if-else, 可以是if-return.
SQL 查询优化
- 先辨认数据库引擎与版本,并检查实际查询、绑定参数、表结构、已有索引、统计信息和典型数据分布。不同数据库的优化器、索引能力和语法可能不同;不要把某个引擎的行为当成通用规则。
- 通过执行计划判断主要成本,关注估算行数与实际行数、扫描范围、连接顺序、循环次数、排序、临时结果、磁盘读写和回表等。若数据允许,比较优化前后的计划和实际行数。
- 根据过滤、连接、排序和分组条件评估索引的列与顺序;组合索引和覆盖索引应由查询模式及执行计划支持。索引会增加存储、写入和维护成本,不能只看读取收益。
- 检查是否有可避免的全表扫描、过早读取大量列、重复子查询、逐行查询(N+1)、不利于索引使用的隐式类型转换或列上函数。每项调整都要结合具体执行计划,不要机械套用规则。
- 保持查询语义,尤其检查
NULL、重复行、外连接、聚合、排序稳定性、分页边界、字符集与排序规则,以及事务和隔离级别。除非业务明确允许,不要为提速改变这些行为。 EXPLAIN ANALYZE在许多数据库中会实际执行语句。只在合适的安全环境中使用;对可能修改数据或产生副作用的语句,先确认影响并选择安全的验证方式。不要未经授权在生产环境运行可能造成高负载的分析查询。- 不要在缺少计划证据时强制使用索引或连接提示,也不要仅为单条查询添加索引而忽略整体读写负载。
- 要注意优化顺序
输出建议
给出简洁的优化说明:瓶颈依据、具体改动、如何确认结果、实际观测到的收益或仍待验证的假设,以及必要的副作用。若当前信息不足以作出可靠修改,先提供最有价值的诊断步骤,并指出缺少哪些信息。
<!-- OB-S:h9VR0DMiVpdILldZGHBHCA -->
微信扫一扫