Oracle数据库SQL优化:理解Optimizer与执行计划

4星 · 超过85%的资源 需积分: 15 5 下载量 79 浏览量 更新于2024-08-02 收藏 556KB PDF 举报
"Oracle数据库的SQL语句优化主要涉及Oracle的Optimizer、执行计划选择以及不同优化模式的理解。本文旨在解答为什么有时SQL不使用已有的索引,并探讨FIRST_ROWS和ALL_ROWS两种查询模式的区别。" Oracle数据库在处理SQL语句时,会通过优化器(Optimizer)来确定最佳的执行计划,以确保查询效率。优化器主要有两种工作模式:基于规则的优化(Rule-Based Optimization, RBO)和基于代价的优化(Cost-Based Optimization, CBO)。 1. **基于规则的优化(RBO)** RBO遵循Oracle内部预定义的一系列规则来决定如何执行SQL语句。例如,如果查询条件中的列有索引,RBO通常会选择使用该索引进行查询。然而,这种方法可能过于简单,无法考虑实际的系统环境和数据分布情况。 2. **基于代价的优化(CBO)** CBO更复杂,它评估各种可能的执行计划,根据CPU成本、I/O成本等资源消耗来选择最优的路径。CBO依赖于表和索引的统计信息,这些信息可以通过执行ANALYZE命令获取和更新。如果统计信息过时,可能导致CBO做出不理想的决策。自Oracle 8以后,CBO成为推荐的优化模式。 3. **优化器的优化模式(Optimizer Mode)** - **Rule** 模式:完全依赖于预定义的规则来选择执行计划。 - **Choose** 模式:Oracle会选择RBO或CBO,取决于哪种方式看起来更有效。 - **First_Rows** 模式:优化器优先考虑返回第一条记录的速度,适合需要快速返回初步结果的情况。 - **All_Rows** 模式:关注整体查询性能,即使延迟返回第一条记录,也要确保获取所有记录时的效率。 4. **索引不被使用的可能性** 即使字段有索引,Oracle也可能选择不使用它。这可能是因为索引的维护成本高、数据分布不均、表的数据量小或者统计信息不准确。例如,对于小表,全表扫描(Full Table Scan, FTS)通常比索引查找更快。 5. **更新统计信息的重要性** 为了确保CBO做出正确的决策,必须定期更新表和索引的统计信息。这可以通过DBMS_STATS包的GATHER_TABLE_STATS和GATHER_INDEX_STATS过程完成。 6. **查询优化技巧** - 使用EXPLAIN PLAN分析SQL执行计划,了解优化器的选择。 - 使用Hints强制优化器采用特定的执行路径,但应谨慎使用,以免影响整体性能。 - 考虑重构SQL,如避免全表扫描、减少JOIN操作或提高WHERE子句的过滤效果。 通过理解Oracle的优化策略和执行计划选择,数据库管理员和开发人员可以更好地调整SQL语句,提高查询效率,从而提升整个系统的性能。
2018-10-08 上传
一、 概念介绍: 数据库DATABASE、表TABLE、列COLUMN、行ROW、关键字PRIMARY KEY、索引INDEX 二、 数据类型: LONG RAM:超长大型数据(照片、图形、描述等不定长数据)。 DATE:包含日期和时间。 INTEGER:有符号全长二进制整数(31位精度)。 SMALLINT:有符号半长二进制整数(15位精度)。 DECIMAL (p[,q]): 有符号的封装了的十进制小数,最多有 p 位数,并假设有 q 位在小数点右边。 如果省略 q ,则认为是 0。 FLOAT:有符号双字浮点数。 CHAR(n): 长度为 n 的定长字符串。 VARCHAR(n): 最大长度为 n 的变长字符串。 CHAR (5) 和 VARCHAR2(5)的区别是 CHAR不足5位后面自动加上空格,VARCHAR2不加 三、 列的非空属性NOT NULL: 如果一个列具有非空属性,则在给该表增加、修改数据时必须保证该列有内容,否则会出错。 如果一个列允许为空,该列可以不放任何内容,即空值(在SQL中书写为NULL),空值不是空格。 如果一个列内容为空值,则该列不等于任何值(包括空值)。 例如:列SAGE1、SAGE2的内容为空,列SAGE3内容为20,则下面的逻辑表达式全部为NULL:SAGE1=SAGE2、SAGE1SAGE2、SAGE1=SAGE3、SAGE3>SAGE1。下面的逻辑表达式全部为真:SAGE1 IS NULL、SAGE3 IS NOT NULL。下列表达式全为空:sage1+100,sage2+sage3 四、 特殊约定: 1. 所有SQL语句以分号结束不是以回车换行结束。 2. 中扩号代表选项,就是其中的内容可有可无。 3. 下面讲的列名在很多情况下也可以是表达式。 4. 表名格式:[用户名.]表名,例如:user001.student,如果不注名用户,则说明是当前登陆的用户的表。 五、 建表或视图语句CREATE 格式: CREATE TABLE 表名 (列名 类型 长度 [NOT NULL], 列名 类型 长度 [NOT NULL], 列名 类型 长度 [NOT NULL], 列名 类型 长度 [NOT NULL], 列名 类型 长度 [NOT NULL]); CREATE VIEW 视图名 AS SELECT ……; CREATE TABLE 表名 AS SELECT ……; Create table as 经常在修改一个表前备份该表,而且运行速度很快且不用提交 例如:Select table a_student as select * from student; Create table as 还可以用来复制表结构 例如:假设有三个表