`
newleague
  • 浏览: 1500841 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类

为什么Oracle有时会用索引来查找数据?--强制Oracle使用最优的“执行计划”

阅读更多
[摘要] 在你运用SQL语言,向数据库发布一条查询语句时,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语句的执行不产生任何影响。
分享到:
评论

相关推荐

    Oracle的执行计划

    此时,可以使用hints来强制Oracle采用某种特定的执行策略。hints是SQL语句中的注释形式,用来指导优化器如何执行查询。 #### 十四、使用全套的hints hints可以覆盖执行计划的各个方面,包括表扫描方式、连接类型等...

    Oracle执行计划不走索引的原因总结

    在Oracle数据库中,执行计划不走索引是一个常见的性能问题,这可能会导致查询效率降低,尤其是在处理大量数据时。以下是一些可能导致Oracle执行计划不选择使用索引的原因及其解决策略。 1. **优化器模式设置**:...

    Oracle优化—SQL优化

    - **索引组织表(Index-Organized Tables, IOTs)**:在这种类型的表中,数据按照索引键的顺序存储,可以直接通过索引键访问数据行,从而避免了额外的索引查找操作。 - **分区(Partitioning)**:通过将表划分为多...

    SQL语句的执行计划优化.doc

    - 索引扫描:利用索引查找数据。 - 全表扫描:遍历整个表。 - **表连接方式**: - 嵌套循环连接:适合小表。 - 哈希连接:适用于大数据量。 - 排序合并连接:适用于有序数据。 - **执行方案生成**: - 根据...

    数据库面试题3 oracle笔试 oracle例题

    1. **实现机制**:当提交SQL语句时,Oracle会在共享池中查找是否存在相同的语句及其执行计划。如果存在,则直接使用已有的执行计划,从而避免了解析过程。 2. **条件限制**:为了实现共享,SQL语句必须完全相同...

    Oracle全表扫描及其执行计划

    收集统计信息后,我们执行`COUNT(*)`查询,此时Oracle会使用索引快速扫描。接下来,通过`ALTER TABLE T MOVE`移动表,这会导致索引失效。在这种情况下,再次执行`COUNT(*)`,Oracle会进行全表扫描,因为无法使用索引...

    Oracle DBA日常巡检最佳实践

    - **目的**:确保Oracle CBO优化器基于最新的统计信息来选择最优的执行计划。 - **方法**:使用`DBMS_STATS`包中的`GATHER_SCHEMA_STATS`过程来更新表的统计信息。 **5.8 检查缓冲区命中率** - **目的**:评估数据...

    ORACLE培训SQL性能优化.pptx

    - 优化过程包括定位问题SQL、分析执行计划、检查统计信息、改写SQL、使用HINT、调整索引等步骤。 2. **性能调整综述**: - 好的SQL语句应简洁、模块化,易于理解和维护,同时应尽可能减少对系统资源(如内存、CPU...

    oracle sql优化 30例

    例如,使用EXPLAIN PLAN分析SQL执行计划,查找是否使用了索引。 3. **选择合适的连接方式**:JOIN操作是SQL中常见的数据合并方式,应根据数据分布和查询需求选择INNER JOIN、LEFT JOIN或RIGHT JOIN。优化JOIN时,...

    Oracle高性能SQL调整

    8. **SQL Profile和SQL Plan Baseline**:Oracle 10g引入的SQL Profile用于改善执行计划,而SQL Plan Baseline则是从11g开始提供的功能,用于保存和强制执行优秀的执行计划,防止因数据分布变化导致的性能下降。...

    oracle CBO HINT

    Oracle的Cost-Based Optimizer (CBO) 是一种自动选择最优执行计划的机制,它通过评估不同执行路径的成本来决定如何执行SQL查询。CBO会考虑各种因素,包括表的大小、索引的存在、数据分布等,以确定最有效率的查询...

    ORACLE优化

    当优化器选择的默认连接方法不是最优时,可以通过`USE_NL`提示来指导优化器使用嵌套循环连接,以提高查询效率。例如,在两个大表进行连接操作时,如果数据分布不均或者有明显的过滤条件,使用`USE_NL`提示可能会比...

    《Pro Oracle SQL》 10.2.4 Seizing Other Optimization Opportunities

    Oracle依赖这些统计信息来决定最优的执行计划。定期收集和更新统计信息可以确保优化器做出正确的决策,避免因统计信息过时而导致的低效查询计划。 总的来说,《Pro Oracle SQL》的10.2.4章节强调了在SQL查询优化...

    阿里巴巴公司DBA笔试题

    - Oracle数据库会评估索引的使用成本,只有当使用索引的成本低于全表扫描时才会使用索引。 9. **绑定变量是什么?绑定变量有什么优缺点** - **定义**:用于替代SQL语句中的实际值的占位符。 - **优点**: - ...

    19_调试sql语句1

    执行此命令后,你可以查询名为“plan table”的特殊表,以获取Oracle为该查询打算使用的执行计划。执行计划通常显示了数据如何被访问、索引是否被使用等信息。 在上述例子中,执行计划简单地显示为“TABLE ACCESS ...

    Oracle DBA 笔试题

    2. 重构索引通常涉及重建索引,可以通过`ALTER INDEX REBUILD`命令实现,或者在索引碎片过多时,考虑使用`ALTER INDEX REORGANIZE`来优化。 3. 表连接方式有:`INNER JOIN`(内连接)、`LEFT JOIN`(左连接)、`...

    SQL语句优化过程策略,帮助您优化Oracle查询语句

    - **含义**:此提示强制使用指定的索引进行查找。 - **应用场景**:当某个索引特别适合当前查询时使用。 - **示例**: ```sql SELECT /*+ INDEX(BSEMPMS SEX_INDEX) */ * FROM BSEMPMS WHERE SEX = 'M'; ``` ###...

    sql优化心得

    - 如果发现某些查询总是选择次优路径,可以通过显式指定优化器模式或使用HINTs来强制Oracle使用特定的优化规则。 通过以上这些技巧和实践,我们可以显著提高SQL查询的性能,特别是在处理大规模数据集时。此外,...

    2021-2022计算机二级等级考试试题及答案No.3731.docx

    12. ASP的代码是解释执行的,但性能并不是最优,因为解释执行通常比编译执行慢。 13. 对于给定的二叉树,中序遍历结果为DBEAFC。 14. 正确的字符常量是C.'W'。字符常量要用单引号括起来。 15. 电子邮件的投递几乎...

Global site tag (gtag.js) - Google Analytics