Oracle 数据库SQL优化指南


一、常见不走索引的情况

  1. 在 WHERE 子句中对索引列使用函数或表达式
    • 示例:SELECT * FROM employees WHERE UPPER(last_name) = 'SMITH';
    • 示例:SELECT * FROM employees WHERE salary * 1.1 > 5000;
      原因:函数或计算会导致索引失效。
  2. 对索引列进行隐式或显式类型转换
    • 示例:SELECT * FROM employees WHERE phone_number = 1234567;(phone_number 为字符串类型)
      原因:类型转换导致索引无法使用。
  3. 使用不等于操作符(<> 或 !=)
    • 示例:SELECT * FROM employees WHERE department_id <> 10;
  4. 使用前导通配符的 LIKE 查询
    • 不走索引:LIKE '%son' 或 LIKE '%son%'
    • 走索引:LIKE 'son%'
  5. 使用 IS NULL 或 IS NOT NULL
    注意:除非是位图索引或索引包含 NULL 值,否则通常不走索引。
  6. 使用 NOT IN
    建议:尽量改写为 NOT EXISTS 或其他等价形式。

二、避免创建重复索引性能瓶颈:

重复索引(如 idx1(col1,col2,col3)、idx2(col1)、idx3(col1,col2))会占用大量空间,并显著降低 DML 操作性能。优化方案:

分析索引使用情况,删除冗余索引,只保留最优的复合索引。


三、避免整个批量过程使用一个大事务性能瓶颈:

单个大事务提交时间长,异常时回滚耗时久,不支持断点续跑,容易影响联机业务。优化方案:

根据业务逻辑拆分成多个小事务,阶段性提交,支持断点续跑。


四、LOB 字段不能设置为 NOLOGGING性能瓶颈:

表设置为 NOLOGGING 时,LOB 对象也会跟随,导致并发环境下产生大量 enq: CF - contention 等待,严重影响性能。优化方案:

表和对应的 LOB 对象均设置为 LOGGING。


五、时间字段不建议使用 VARCHAR2/CHAR/NUMBER 类型性能瓶颈:

统计信息 LOW_VALUE 和 HIGH_VALUE 以 NUMBER 形式存储,导致执行计划估算偏差大,SQL 效率低下。优化方案:

统一使用 DATE 或 TIMESTAMP 类型。


六、大表建议进行分区分区优点:

  • 显著提升查询性能(分区剪枝)
  • 改善高并发插入性能(尤其是 Hash 分区)
  • 增强可用性(分区故障不影响其他分区)
  • 维护方便(快速清理历史数据)
  • 均衡 I/O

建议:表大小超过 10GB 或行数超过 1000万 时,建议进行分区。


七、Sequence 的最佳实践

  • CACHE SIZE:高并发场景建议调大(默认 20 太小),避免频繁更新数据字典。

  • ORDER Flag:RAC 环境下建议保持 NOORDER,避免 enq: SV - contention。

  • Keep 在内存中(可选):sql

    复制代码
    EXEC DBMS_SHARED_POOL.KEEP('SCHEMA.SEQUENCE_NAME', 'Q');

八、不建议使用触发器实现基础数据操作性能瓶颈:

增加 SQL 与 PL/SQL 引擎切换开销,业务逻辑分散,维护困难,迁移风险高。优化建议:

基础数据操作逻辑尽量放在应用层实现。


九、避免创建带限制视图合并的视图性能瓶颈:

包含 UNION/UNION ALL/INTERSECT/MINUS/CONNECT BY/ROWNUM 的视图无法进行视图合并,导致 SQL 效率低下。优化建议:视图定义中尽量避免上述语法。


十、绑定变量的正确使用使用场景(推荐绑定变量):

  • 过滤条件值变化非常多(如账号、姓名、订单号等)
  • SQL 执行频率高

不使用绑定变量场景:

  • 过滤条件值很少且分布不均衡(如性别、状态、类型等)

十一、OLTP 系统避免使用位图索引性能瓶颈:

位图索引锁粒度大,高并发下容易产生大量行锁和死锁。优化建议:OLTP 表一律不使用位图索引。


十二、避免一次性 DELETE 大量数据后 COMMIT性能瓶颈:

会导致后续 INSERT 性能急剧下降(Bitmap Block 维护问题)。优化方案:

分批 DELETE + 多次 COMMIT,建议在业务低峰期执行。


十三、分区表 TRUNCATE/DROP 分区需注意全局索引问题:操作后全局索引会失效。

复制代码
ALTER TABLE table_name TRUNCATE PARTITION p1 UPDATE GLOBAL INDEXES;

十四、控制类似流水号的生成规则性能瓶颈:

单调递增的序列 + 索引会导致热点块竞争。

优化建议:采用前缀 + 随机序列等方式,避免单向递增。


十五、注意表和索引的默认并行度性能瓶颈:

默认并行度 > 1 时,全表扫描和索引快速全扫描都会并行,消耗大量 CPU 和 IO。优化建议:sql

复制代码
ALTER TABLE t1 PARALLEL 1;
ALTER INDEX idx1 NOPARALLEL;
相关推荐
j7~14 小时前
【MYSQL】 内置函数--详解
数据库·mysql·字符串函数·内置函数·日期函数·数学函数
whn197714 小时前
ORACLE异常sql解析的案例
数据库·sql·oracle
夏贰四14 小时前
用好数据建模工具能解决哪些问题?如何正确选用建模工具?
大数据·数据库·数学建模·数据建模工具
小欣加油14 小时前
Hadoop开发环境搭建
大数据·数据库·hadoop
我是一颗柠檬14 小时前
【MySQL全面教学】MySQL存储过程与函数Day11(2026年)
数据库·后端·mysql
霸道流氓气质14 小时前
外部系统回调的异步处理架构:接收、落库、MQ消费、推送的完整设计
数据库·架构
程序猿乐锅14 小时前
【MySQL | 第三篇】MySQL存储引擎详解
数据库·mysql
TDengine (老段)14 小时前
TDengine 数据文件格式 — TSDB 文件集的物理结构与块编码
大数据·数据库·物联网·时序数据库·iot·tdengine·涛思数据
热爱Liunx的丘丘人14 小时前
搭建一个 Web + 数据库系统(Nginx+PHP+MySQL)
数据库·nginx·php