硬解析比软解析开销大得多,因需完整执行词法分析、语法校验、权限检查、多计划生成、成本估算、最优选择及共享池缓存,且争抢latch、消耗cpu;软解析仅在sql文本、对象定义、优化器环境、绑定变量完全一致时复用执行计划。

SQL硬解析比软解析开销大得多,核心区别在于是否跳过语法检查、语义分析和执行计划生成等步骤。当数据库能复用已缓存的执行计划时,就走软解析,效率高;否则必须从头解析,即硬解析——这会争抢latch、消耗CPU,尤其在高并发场景下容易成为瓶颈。
硬解析到底做了什么
硬解析是完整解析流程:词法分析 → 语法校验 → 对象权限与存在性检查 → 生成多个候选执行计划 → 成本估算 → 选择最优计划 → 缓存进库共享池(Shared Pool)。每一步都需持有library cache latch等关键锁,且涉及大量内存分配与哈希查找。例如一条未绑定变量的SELECT * FROM orders WHERE order_id = 12345,每次ID不同都会触发全新硬解析。
软解析的关键前提
软解析成立需同时满足:SQL文本完全一致(含空格、大小写)、所访问对象的定义未变更、优化器环境(如optimizer_mode)相同、绑定变量类型与个数匹配。只要其中一项变化,就会降级为硬解析或“软软解析”(仅跳过部分步骤但仍需校验)。常见破坏软解析的行为包括:
• 拼接SQL字符串而非使用绑定变量
• 同一应用中混用SELECT * FROM t和select * from t
• 在SQL中嵌入TO_DATE('2024-01-01','YYYY-MM-DD')这类字面量
降低硬解析频率的实操方法
重点不是消灭硬解析,而是让可复用的SQL尽量走软解析:
• 统一使用绑定变量,尤其WHERE条件和DML中的值字段
• 应用层启用PreparedStatement(Java)或sp_executesql(SQL Server)
• 关闭游标共享相关限制参数(如Oracle的_cursor_plan_unload_time设为0)
• 定期清理Shared Pool中陈旧/低频SQL(谨慎操作,避免误伤热点语句)
• 监控v$sqlarea视图,识别PARSE_CALLS远大于EXECUTIONS的SQL,针对性改造
硬解析并非绝对要避免
少量硬解析不可避免,比如首次执行新SQL、统计信息更新后计划失效、使用了动态SQL等。关键是控制其比例:生产库中硬解析占比长期超过5%就值得排查。比起盲目追求零硬解析,更应关注单次硬解析耗时是否异常(如超10ms),以及library cache lock/latch等待是否突增——这才是真实影响性能的信号。










