- 浏览: 1500841 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (798)
- struts2 (42)
- servlet (20)
- quartz (4)
- jquery & ajax (24)
- tomcat (5)
- javascript (15)
- struts1 (8)
- 搜索关键字及链接 (3)
- fckeditor (3)
- Apache (5)
- spring (22)
- linux (3)
- 企业应用 (8)
- 综合应用 (13)
- 服务器 (2)
- 数据库 (85)
- 性能调优 (21)
- 网络应用 (15)
- 缓存技术 (8)
- 设计模式 (39)
- 面试题 (7)
- 程序人生&前辈程序员 (29)
- java基础 (59)
- hibernate (75)
- log4j (4)
- http (11)
- 架构设计 (28)
- 网页设计 (12)
- java邮件 (4)
- 相关工具 (11)
- ognl (7)
- 工作笔记 (18)
- 知识面扩展 (12)
- oracle异常 (1)
- 正则表达式 (2)
- java异常 (5)
- 项目实践&管理 (1)
- 专业术语 (11)
- 网站参考 (1)
- 论坛话题 (2)
- web应用 (11)
- cxf&webservice (22)
- freemarker (3)
- 开源项目 (9)
- eos (1)
- ibatis (6)
- 自定义标签 (3)
- jsp (3)
- 内部非公开文档(注意:保存为草稿) (0)
- 国内外知名企业 (2)
- 网店 (3)
- 分页 (1)
- 消费者习惯 (2)
- 每日关注 (1)
- 商业信息 (18)
- 关注商业网站 (1)
- 生活常识 (3)
- 新闻 (2)
- xml&JSON (5)
- solaris (1)
- apache.common (3)
- BLOB/CLOB (1)
- lucene (2)
- JMS (14)
- 社会进程 (8)
- SSH扩展 (2)
- 消费心理 (1)
- 珠三角 (1)
- 设计文档 (1)
- XWork&webwork (1)
- 软件工程 (3)
- 数据库及链接 (1)
- RMI (2)
- 国内外知名企业&人物 (1)
最新评论
-
司c马:
简介易懂、
OutputStream和InputStream的区别 -
在世界的中心呼喚愛:
解决我的问题
Java获取客户端的真实IP地址 -
bo_hai:
都是些基本的概念呀!
SSO -
tian_4238:
哥们,你也是搞水利这块的吧。
巧用SQLQuery中的addScalar -
loveEVERYday:
java.util.Date、java.sql.Date、java.sql.Time、java.sql.Timestamp小结
[摘要] 在你运用SQL语言,向数据库发布一条查询语句时,Oracle将伴随产生一个“执行计划”,也就是该语句将通过何种数据搜索方案执行。搜索方案的选用与Oracle的优化器息息相关。
[关键字] Oracle 索引 查找数据
[关键字] Oracle 索引 查找数据
问:为什么Oracle有时会用索引来查找数据?
答:在你运用SQL语言,向数据库发布一条查询语句时,Oracle将伴随产生一个“执行计划”,也就是该语句将通过何种数据搜索方案执行,是通过全表扫描、还是通过索引搜寻等其它方式。搜索方案的选用与Oracle的优化器息息相关。
SQL语句的执行步骤
一条SQL语句的处理过程要经过以下几个步骤。
1 语法分析 分析语句的语法是否符合规范,衡量语句中各表达式的意义。
2 语义分析 检查语句中涉及的所有数据库对象是否存在,且用户有相应的权限。
3 视图转换 将涉及视图的查询语句转换为相应的对基表查询语句。
4 表达式转换 将复杂的SQL表达式转换为较简单的等效连接表达式。
5 选择优化器 不同的优化器一般产生不同的“执行计划”
6 选择连接方式 Oracle有三种连接方式,对多表连接Oracle可选择适当的连接方式。
7 选择连接顺序 对多表连接Oracle选择哪一对表先连接,选择这两表中哪个表做为源数据表。
8 选择数据的搜索路径 根据以上条件选择合适的数据搜索路径,如是选用全表搜索还是利用索引或是其他的方式。
9 运行“执行计划”
Oracle的优化器
Oracle有两种优化器:基于规则的优化器(RBO, Rule Based Optimizer),和基于代价的优化器(CBO, Cost Based Optimizer)。
RBO自Oracle 6版以来被采用,有着一套严格的使用规则,只要你按照它去写SQL语句,无论数据表中的内容怎样,也不会影响到你的“执行计划”,也就是说对数据不“敏感”,Oracle公司已经不再发展这种技术了。
CBO自Oracle 7版被引入,Oracle自7版以来采用的许多新技术都是基于CBO的,如星型连接排列查询,哈希连接查询,和并行查询等。CBO计算各种可能“执行计划”的“代价”,即cost,从中选用cost最低的方案,作为实际运行方案。各“执行计划”的cost的计算根据,依赖于数据表中数据的统计分布,Oracle数据库本身对该统计分布并不清楚,须要分析表和相关的索引,才能搜集到CBO所需的数据。
一般而言,CBO所选择的“执行计划”都不会比RBO的“执行计划”差,而且相对而言,CBO对程序员的要求没有RBO那么苛刻,节省了程序员为了从多个可能的“执行计划”中选择一个最优的方案而花费的调试时间,但在某些场合下也会存在问题。
较典型的问题有:有时,表明明建有索引,但查询过程显然没有用到相关的索引,导致查询过程耗时漫长,占用资源巨大,问题到底出在哪儿呢?按照以下顺序查找,基本上能发现原因所在。
查找原因的步骤
首先,我们要确定数据库运行在何种优化模式下,相应的参数是:optimizer_mode。可在svrmgrl中运行“show parameter optimizer_mode"来查看。Oracle V7以来缺省的设置应是"choose",即如果对已分析的表查询的话选择CBO,否则选择RBO。如果该参数设为“rule”,则不论表是否分析过,一概选用RBO,除非在语句中用hint强制。
其次,检查被索引的列或组合索引的首列是否出现在PL/SQL语句的WHERE子句中,这是“执行计划”能用到相关索引的必要条件。
第三,看采用了哪种类型的连接方式。Oracle的共有Sort Merge Join(SMJ)、Hash Join(HJ)和Nested Loop Join(NL)。在两张表连接,且内表的目标列上建有索引时,只有Nested Loop才能有效地利用到该索引。SMJ即使相关列上建有索引,最多只能因索引的存在,避免数据排序过程。HJ由于须做HASH运算,索引的存在对数据查询速度几乎没有影响。
第四,看连接顺序是否允许使用相关索引。假设表emp的deptno列上有索引,表dept的列deptno上无索引,Where语句有emp.deptno=dept.deptno条件。在做NL连接时,emp做为外表,先被访问,由于连接机制原因,外表的数据访问方式是全表扫描,emp.deptno上的索引显然是用不上,最多在其上做索引全扫描或索引快速全扫描。
第五,是否用到系统数据字典表或视图。由于系统数据字典表都未被分析过,可能导致极差的“执行计划”。但是不要擅自对数据字典表做分析,否则可能导致死锁,或系统性能下降。
第六,索引列是否函数的参数。如是,索引在查询时用不上。
第七,是否存在潜在的数据类型转换。如将字符型数据与数值型数据比较,Oracle会自动将字符型用to_number()函数进行转换,从而导致第六种现象的发生。
第八,是否为表和相关的索引搜集足够的统计数据。对数据经常有增、删、改的表最好定期对表和索引进行分析,可用SQL语句:
analyze table xxxx compute statistics for all indexes;
Oracle掌握了充分反映实际的统计数据,才有可能做出正确的选择。
第九,索引列的选择性不高。
我们假设典型情况,有表emp,共有一百万行数据,但其中的emp.deptno列,数据只有4种不同的值,如10、20、30、40。虽然emp数据行有很多,Oracle缺省认定表中列的值是在所有数据行均匀分布的,也就是说每种deptno值各有25万数据行与之对应。假设SQL搜索条件DEPTNO=10,利用deptno列上的索引进行数据搜索效率,往往不比全表扫描的高,ORACLE理所当然对索引“视而不见”,认为该索引的选择性不高。
但我们考虑另一种情况,如果一百万数据行实际不是在4种deptno值间平均分配,其中有99万行对应着值10,5000行对应值20,3000行对应值30,2000行对应值40。在这种数据分布图案中对除值为10外的其它deptno值搜索时,毫无疑问,如果索引能被应用,那么效率会高出很多。我们可以采用对该索引列进行单独分析,或用analyze语句对该列建立直方图,对该列搜集足够的统计数据,使Oracle在搜索选择性较高的值能用上索引。
第十,索引列值是否可为空(NULL)。如果索引列值可以是空值,在SQL语句中那些需要返回NULL值的操作,将不会用到索引,如COUNT(*),而是用全表扫描。这是因为索引中存储值不能为全空。
第十一,看是否有用到并行查询(PQO)。并行查询将不会用到索引。
第十二,看PL/SQL语句中是否有用到bind变量。由于数据库不知道bind变量具体是什么值,在做非相等连接时,如“<”,“>”,“like”等。Oracle将引用缺省值,在某些情况下会对执行计划造成影响。
如果从以上几个方面都查不出原因的话,我们只好用采用在语句中加hint的方式强制Oracle使用最优的“执行计划”。
hint采用注释的方式,有行注释和段注释两种方式。
如我们想要用到A表的IND_COL1索引的话,可采用以下方式:
“SELECT /*+ INDEX(A IND_COL1)*/ * FROM A WHERE COL1 = XXX; "
注意,注释符必须跟在SELECT之后,且注释中的“+”要紧跟着注释起始符“/*”或“--”,否则hint就被认为是一般注释,对PL/SQL语句的执行不产生任何影响。
答:在你运用SQL语言,向数据库发布一条查询语句时,Oracle将伴随产生一个“执行计划”,也就是该语句将通过何种数据搜索方案执行,是通过全表扫描、还是通过索引搜寻等其它方式。搜索方案的选用与Oracle的优化器息息相关。
SQL语句的执行步骤
一条SQL语句的处理过程要经过以下几个步骤。
1 语法分析 分析语句的语法是否符合规范,衡量语句中各表达式的意义。
2 语义分析 检查语句中涉及的所有数据库对象是否存在,且用户有相应的权限。
3 视图转换 将涉及视图的查询语句转换为相应的对基表查询语句。
4 表达式转换 将复杂的SQL表达式转换为较简单的等效连接表达式。
5 选择优化器 不同的优化器一般产生不同的“执行计划”
6 选择连接方式 Oracle有三种连接方式,对多表连接Oracle可选择适当的连接方式。
7 选择连接顺序 对多表连接Oracle选择哪一对表先连接,选择这两表中哪个表做为源数据表。
8 选择数据的搜索路径 根据以上条件选择合适的数据搜索路径,如是选用全表搜索还是利用索引或是其他的方式。
9 运行“执行计划”
Oracle的优化器
Oracle有两种优化器:基于规则的优化器(RBO, Rule Based Optimizer),和基于代价的优化器(CBO, Cost Based Optimizer)。
RBO自Oracle 6版以来被采用,有着一套严格的使用规则,只要你按照它去写SQL语句,无论数据表中的内容怎样,也不会影响到你的“执行计划”,也就是说对数据不“敏感”,Oracle公司已经不再发展这种技术了。
CBO自Oracle 7版被引入,Oracle自7版以来采用的许多新技术都是基于CBO的,如星型连接排列查询,哈希连接查询,和并行查询等。CBO计算各种可能“执行计划”的“代价”,即cost,从中选用cost最低的方案,作为实际运行方案。各“执行计划”的cost的计算根据,依赖于数据表中数据的统计分布,Oracle数据库本身对该统计分布并不清楚,须要分析表和相关的索引,才能搜集到CBO所需的数据。
一般而言,CBO所选择的“执行计划”都不会比RBO的“执行计划”差,而且相对而言,CBO对程序员的要求没有RBO那么苛刻,节省了程序员为了从多个可能的“执行计划”中选择一个最优的方案而花费的调试时间,但在某些场合下也会存在问题。
较典型的问题有:有时,表明明建有索引,但查询过程显然没有用到相关的索引,导致查询过程耗时漫长,占用资源巨大,问题到底出在哪儿呢?按照以下顺序查找,基本上能发现原因所在。
查找原因的步骤
首先,我们要确定数据库运行在何种优化模式下,相应的参数是:optimizer_mode。可在svrmgrl中运行“show parameter optimizer_mode"来查看。Oracle V7以来缺省的设置应是"choose",即如果对已分析的表查询的话选择CBO,否则选择RBO。如果该参数设为“rule”,则不论表是否分析过,一概选用RBO,除非在语句中用hint强制。
其次,检查被索引的列或组合索引的首列是否出现在PL/SQL语句的WHERE子句中,这是“执行计划”能用到相关索引的必要条件。
第三,看采用了哪种类型的连接方式。Oracle的共有Sort Merge Join(SMJ)、Hash Join(HJ)和Nested Loop Join(NL)。在两张表连接,且内表的目标列上建有索引时,只有Nested Loop才能有效地利用到该索引。SMJ即使相关列上建有索引,最多只能因索引的存在,避免数据排序过程。HJ由于须做HASH运算,索引的存在对数据查询速度几乎没有影响。
第四,看连接顺序是否允许使用相关索引。假设表emp的deptno列上有索引,表dept的列deptno上无索引,Where语句有emp.deptno=dept.deptno条件。在做NL连接时,emp做为外表,先被访问,由于连接机制原因,外表的数据访问方式是全表扫描,emp.deptno上的索引显然是用不上,最多在其上做索引全扫描或索引快速全扫描。
第五,是否用到系统数据字典表或视图。由于系统数据字典表都未被分析过,可能导致极差的“执行计划”。但是不要擅自对数据字典表做分析,否则可能导致死锁,或系统性能下降。
第六,索引列是否函数的参数。如是,索引在查询时用不上。
第七,是否存在潜在的数据类型转换。如将字符型数据与数值型数据比较,Oracle会自动将字符型用to_number()函数进行转换,从而导致第六种现象的发生。
第八,是否为表和相关的索引搜集足够的统计数据。对数据经常有增、删、改的表最好定期对表和索引进行分析,可用SQL语句:
analyze table xxxx compute statistics for all indexes;
Oracle掌握了充分反映实际的统计数据,才有可能做出正确的选择。
第九,索引列的选择性不高。
我们假设典型情况,有表emp,共有一百万行数据,但其中的emp.deptno列,数据只有4种不同的值,如10、20、30、40。虽然emp数据行有很多,Oracle缺省认定表中列的值是在所有数据行均匀分布的,也就是说每种deptno值各有25万数据行与之对应。假设SQL搜索条件DEPTNO=10,利用deptno列上的索引进行数据搜索效率,往往不比全表扫描的高,ORACLE理所当然对索引“视而不见”,认为该索引的选择性不高。
但我们考虑另一种情况,如果一百万数据行实际不是在4种deptno值间平均分配,其中有99万行对应着值10,5000行对应值20,3000行对应值30,2000行对应值40。在这种数据分布图案中对除值为10外的其它deptno值搜索时,毫无疑问,如果索引能被应用,那么效率会高出很多。我们可以采用对该索引列进行单独分析,或用analyze语句对该列建立直方图,对该列搜集足够的统计数据,使Oracle在搜索选择性较高的值能用上索引。
第十,索引列值是否可为空(NULL)。如果索引列值可以是空值,在SQL语句中那些需要返回NULL值的操作,将不会用到索引,如COUNT(*),而是用全表扫描。这是因为索引中存储值不能为全空。
第十一,看是否有用到并行查询(PQO)。并行查询将不会用到索引。
第十二,看PL/SQL语句中是否有用到bind变量。由于数据库不知道bind变量具体是什么值,在做非相等连接时,如“<”,“>”,“like”等。Oracle将引用缺省值,在某些情况下会对执行计划造成影响。
如果从以上几个方面都查不出原因的话,我们只好用采用在语句中加hint的方式强制Oracle使用最优的“执行计划”。
hint采用注释的方式,有行注释和段注释两种方式。
如我们想要用到A表的IND_COL1索引的话,可采用以下方式:
“SELECT /*+ INDEX(A IND_COL1)*/ * FROM A WHERE COL1 = XXX; "
注意,注释符必须跟在SELECT之后,且注释中的“+”要紧跟着注释起始符“/*”或“--”,否则hint就被认为是一般注释,对PL/SQL语句的执行不产生任何影响。
发表评论
-
SQL查询顺序处理
2011-09-15 11:29 1629select的解析执行顺序1. from语句 2. where ... -
概念模型、逻辑模型、物理模型区别
2011-09-08 10:48 1232http://wenku.baidu.com/view/9a6 ... -
规范化-数据库设计原则
2011-09-07 10:41 1453简介: 关系数据库设计的核心问题是关系模型的设计。本文将结合具 ... -
数据库设计准则(第一、第二、第三范式说明)
2011-09-07 10:17 1278I、关系数据库设计范式 ... -
oracle日志文件及归档日志模式
2011-09-01 10:18 1759oracle数据库中分为联机日志文件和归档日志文件两种日志文件 ... -
Oracle重做日志管理
2011-09-01 09:50 1437Oracle重做日志操作是为了记录数据的改变,提供数据库 ... -
Oracle复制技术的分布式系统同步应用
2011-08-28 17:41 1293本文将结合一个实际案例,讲解Oracle复制技术在分布 ... -
oracle数据同步
2011-08-28 14:34 994首先创建一个 dblink(dat ... -
Oracle 流复制(Stream Replication)
2011-07-20 10:37 5625Stream 是Oracle 的消息队列( ... -
表分区
2011-06-30 09:21 1679分区表: 当表中的数据量不断增大,查询数据的速度就会变慢,应用 ... -
数据库大型应用解决方案总结(1)
2011-06-22 18:01 1392随着互联网应用的广泛普及,海量数据的存储和访问成为了系统设 ... -
oracle_SQL中ROWID与ROWNUM的使用
2011-06-16 10:51 1425对于 Oracle 的 rownum 问题,很多资料都说不支持 ... -
oracle函数手册
2011-06-08 09:22 1184SQL中的单记录函数1.ASCII ... -
oracle基础文档
2011-06-03 09:10 1240oracle基础文档 -
ORACLE 找回误删的数据库
2011-06-02 14:14 1371同事找回时操作的数据库为oracle 10g , 之前删除方式 ... -
sql编程规范与性能
2011-05-31 08:40 1277sql编程规范与性能 -
Nested Loops Join(嵌套连接)
2011-04-13 16:21 11576说明:最近找到了一个 ... -
如何看Oracle执行计划
2011-01-14 15:43 2187oracle执行计划解释 ... -
oracle中分析sql语句执行计划的方法
2011-01-14 15:36 2229如何生成explain plan? 解答:运行utl ... -
oracle sql 语句(二)
2010-12-10 09:17 144527建立序列:(注意,这里并没有出现说是哪个表里面的序列 ...
相关推荐
此时,可以使用hints来强制Oracle采用某种特定的执行策略。hints是SQL语句中的注释形式,用来指导优化器如何执行查询。 #### 十四、使用全套的hints hints可以覆盖执行计划的各个方面,包括表扫描方式、连接类型等...
在Oracle数据库中,执行计划不走索引是一个常见的性能问题,这可能会导致查询效率降低,尤其是在处理大量数据时。以下是一些可能导致Oracle执行计划不选择使用索引的原因及其解决策略。 1. **优化器模式设置**:...
- **索引组织表(Index-Organized Tables, IOTs)**:在这种类型的表中,数据按照索引键的顺序存储,可以直接通过索引键访问数据行,从而避免了额外的索引查找操作。 - **分区(Partitioning)**:通过将表划分为多...
- 索引扫描:利用索引查找数据。 - 全表扫描:遍历整个表。 - **表连接方式**: - 嵌套循环连接:适合小表。 - 哈希连接:适用于大数据量。 - 排序合并连接:适用于有序数据。 - **执行方案生成**: - 根据...
1. **实现机制**:当提交SQL语句时,Oracle会在共享池中查找是否存在相同的语句及其执行计划。如果存在,则直接使用已有的执行计划,从而避免了解析过程。 2. **条件限制**:为了实现共享,SQL语句必须完全相同...
收集统计信息后,我们执行`COUNT(*)`查询,此时Oracle会使用索引快速扫描。接下来,通过`ALTER TABLE T MOVE`移动表,这会导致索引失效。在这种情况下,再次执行`COUNT(*)`,Oracle会进行全表扫描,因为无法使用索引...
- **目的**:确保Oracle CBO优化器基于最新的统计信息来选择最优的执行计划。 - **方法**:使用`DBMS_STATS`包中的`GATHER_SCHEMA_STATS`过程来更新表的统计信息。 **5.8 检查缓冲区命中率** - **目的**:评估数据...
- 优化过程包括定位问题SQL、分析执行计划、检查统计信息、改写SQL、使用HINT、调整索引等步骤。 2. **性能调整综述**: - 好的SQL语句应简洁、模块化,易于理解和维护,同时应尽可能减少对系统资源(如内存、CPU...
例如,使用EXPLAIN PLAN分析SQL执行计划,查找是否使用了索引。 3. **选择合适的连接方式**:JOIN操作是SQL中常见的数据合并方式,应根据数据分布和查询需求选择INNER JOIN、LEFT JOIN或RIGHT JOIN。优化JOIN时,...
8. **SQL Profile和SQL Plan Baseline**:Oracle 10g引入的SQL Profile用于改善执行计划,而SQL Plan Baseline则是从11g开始提供的功能,用于保存和强制执行优秀的执行计划,防止因数据分布变化导致的性能下降。...
Oracle的Cost-Based Optimizer (CBO) 是一种自动选择最优执行计划的机制,它通过评估不同执行路径的成本来决定如何执行SQL查询。CBO会考虑各种因素,包括表的大小、索引的存在、数据分布等,以确定最有效率的查询...
当优化器选择的默认连接方法不是最优时,可以通过`USE_NL`提示来指导优化器使用嵌套循环连接,以提高查询效率。例如,在两个大表进行连接操作时,如果数据分布不均或者有明显的过滤条件,使用`USE_NL`提示可能会比...
Oracle依赖这些统计信息来决定最优的执行计划。定期收集和更新统计信息可以确保优化器做出正确的决策,避免因统计信息过时而导致的低效查询计划。 总的来说,《Pro Oracle SQL》的10.2.4章节强调了在SQL查询优化...
- Oracle数据库会评估索引的使用成本,只有当使用索引的成本低于全表扫描时才会使用索引。 9. **绑定变量是什么?绑定变量有什么优缺点** - **定义**:用于替代SQL语句中的实际值的占位符。 - **优点**: - ...
执行此命令后,你可以查询名为“plan table”的特殊表,以获取Oracle为该查询打算使用的执行计划。执行计划通常显示了数据如何被访问、索引是否被使用等信息。 在上述例子中,执行计划简单地显示为“TABLE ACCESS ...
2. 重构索引通常涉及重建索引,可以通过`ALTER INDEX REBUILD`命令实现,或者在索引碎片过多时,考虑使用`ALTER INDEX REORGANIZE`来优化。 3. 表连接方式有:`INNER JOIN`(内连接)、`LEFT JOIN`(左连接)、`...
- **含义**:此提示强制使用指定的索引进行查找。 - **应用场景**:当某个索引特别适合当前查询时使用。 - **示例**: ```sql SELECT /*+ INDEX(BSEMPMS SEX_INDEX) */ * FROM BSEMPMS WHERE SEX = 'M'; ``` ###...
- 如果发现某些查询总是选择次优路径,可以通过显式指定优化器模式或使用HINTs来强制Oracle使用特定的优化规则。 通过以上这些技巧和实践,我们可以显著提高SQL查询的性能,特别是在处理大规模数据集时。此外,...
12. ASP的代码是解释执行的,但性能并不是最优,因为解释执行通常比编译执行慢。 13. 对于给定的二叉树,中序遍历结果为DBEAFC。 14. 正确的字符常量是C.'W'。字符常量要用单引号括起来。 15. 电子邮件的投递几乎...