热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

Oracle优化SQL语句

我们都了解索引是相关表概念部分,主要是提高检索数据的相关效率,当Oracle使用了较为复杂的自平衡B-tree结构时。我们一般是通过索引查询数据比全表扫描要快。当Oracle找出执行查询和Update语句的最好路径时,Oracle优化将使用索引。同样在联结多个表时使用

我们都了解索引是相关表概念部分,主要是提高检索数据的相关效率,当Oracle使用了较为复杂的自平衡B-tree结构时。我们一般是通过索引查询数据比全表扫描要快。当 Oracle找出执行查询和Update语句的最好路径时,Oracle优化将使用索引。同样在联结多个表时使用

我们都了解索引是相关表概念部分,主要是提高检索数据的相关效率,当Oracle使用了较为复杂的自平衡B-tree结构时。我们一般是通过索引查询数据比全表扫描要快。当 Oracle找出执行查询和Update语句的最好路径时, Oracle优化将使用索引。同样在联结多个表时使用索引也能够提高效率。

另一个使用索引的好处是,他提供了主键(primary key)的唯一性验证。那些LONG或LONG RAW数据类型, 您能够索引几乎任何的列。通常, 在大型表中使用索引特别有效. 当然,您也会发现, 在扫描小表时,使用索引同样能提高效率。虽然使用索引能得到查询效率的提高,但是我们也必须注意到他的代价。

索引需要空间来存储,也需要定期维护, 每当有记录在表中增减或索引列被修改时, 索引本身也会被修改。这意味着每条记录的INSERT,DELETE , UPDATE将为此多付出4、 5次的磁盘I/O 。因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢。定期的重构索引是有必要的:

ALTER INDEX REBUILD

1.用EXISTS替换DISTINCT:

当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT。一般能够考虑用EXIST替换, EXISTS 使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立即返回结果。例子:

(低效): SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D , EMP E WHERE D.DEPT_NO = E.DEPT_NO (高效): SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT ‘X' FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);

2.SQL语句用大写的;因为Oracle总是先解析SQL语句,把小写的字母转换成大写的再执行。

3.在Java代码中尽量少用连接符“+”连接字符串。

4.避免在索引列上使用NOT通常,我们要避免在索引列上使用NOT, NOT会产生在和在索引列上使用函数相同的影响。当Oracle“碰到”NOT,他就会停止使用索引转而执行全表扫描。

5.避免在索引列上使用计算。WHERE子句中,假如索引列是函数的一部分。Oracle优化器将不使用索引而使用全表扫描。

举例:

低效: SELECT … FROM DEPT WHERE SAL * 12 > 25000; 高效: SELECT … FROM DEPT WHERE SAL > 25000/12;

6.用>=替代>:

高效:SELECT * FROM EMP WHERE DEPTNO >=4 低效: SELECT * FROM EMP WHERE DEPTNO >3

两者的区别在于,前者DBMS将直接跳到第一个DEPT等于4的记录而后者将首先定位到DEPTNO=3的记录并且向前扫描到第一个DEPT大于3的记录。

7.用UNION替换OR (适用于索引列):

通常情况下,用UNION替换WHERE子句中的OR将会起到较好的效果。对索引列使用OR将造成全表扫描。注意,以上规则只针对多个索引列有效。假如有column没有被索引,查询效率可能会因为您没有选择OR而降低。在下面的例子中,LOC_ID 和REGION上都建有索引。

高效:SELECT LOC_ID 。 LOC_DESC ,REGION FROM LOCATION WHERE LOC_ID = 10 UNION SELECT LOC_ID ,LOC_DESC ,REGION FROM LOCATION WHERE REGION = “MELBOURNE”

低效: SELECT LOC_ID ,LOC_DESC ,REGION FROM LOCATION WHERE LOC_ID = 10 OR REGION = “MELBOURNE”

8.用IN来替换OR:

这是一条简单易记的规则,但是实际的执行效果还须检验,在Oracle8i下,两者的执行路径似乎是相同的:

低效:

SELECT…. FROM LOCATION WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30

高效:

SELECT… FROM LOCATION WHERE LOC_IN IN (10,20,30);

9.避免在索引列上使用IS NULL和IS NOT NULL:

避免在索引中使用任何能够为空的列,Oracle将无法使用该索引。对于单列索引,假如列包含空值,索引中将不存在此记录。对于复合索引,假如每个列都为空,索引中同样不存在此记录。假如至少有一个列不为空,则记录存在于索引中。举例:假如唯一性索引建立在表的A列和B列上,并且表中存在一条记录的 A,B值为(123,null), Oracle将不接受下一条具备相同A,B值(123,null)的记录(插入)。

然而假如任何的索引列都为空,Oracle将认为整个键值为空而空不等于空。因此您能够插入1000 条具备相同键值的记录,当然他们都是空! 因为空值不存在于索引列中,所以WHERE子句中对索引列进行空值比较将使Oracle停用该索引。

低效: (索引失效)

  1. SELECT … FROM DEPARTMENT WHERE DEPT_CODE IS NOT NULL;

高效:(索引有效)

  1. SELECT … FROM DEPARTMENT WHERE DEPT_CODE >=0;

10.总是使用索引的第一个列:

假如索引是建立在多个列上,只有在他的第一个列(leading column)被where子句引用时,Oracle优化器才会选择使用该索引。这也是一条简单而重要的规则,当仅引用索引的第二个列时,优化器使用了全表扫描而忽略了索引。

11.用UNION-ALL 替换UNION ( 假如有可能的话):

当SQL语句需要UNION两个查询结果集合时,这两个结果集合会以UNION-ALL的方式被合并,然后在输出最终结果前进行排序。假如用 UNION ALL替代UNION,这样排序就不是必要了。效率就会因此得到提高。需要注意的是,UNION ALL 将重复输出两个结果集合中相同记录。因此各位还是要从业务需求分析使用UNION ALL的可行性。 UNION 将对结果集合排序,这个操作会使用到SORT_AREA_SIZE这块内存。对于这块内存的Oracle优化也是相当重要的。下面的SQL能够用来查询排序的消耗量:

低效: SELECT ACCT_NUM, BALANCE_AMT FROM DEBIT_TRANSACTIONS WHERE TRAN_DATE = '31-DEC-95' UNION SELECT ACCT_NUM, BALANCE_AMT FROM DEBIT_TRANSACTIONS WHERE TRAN_DATE = '31-DEC-95' 高效: SELECT ACCT_NUM, BALANCE_AMT FROM DEBIT_TRANSACTIONS WHERE TRAN_DATE = '31-DEC-95' UNION ALL SELECT ACCT_NUM, BALANCE_AMT FROM DEBIT_TRANSACTIONS WHERE TRAN_DATE = '31-DEC-95'


如果你是Oracle多表查询优化方面的新手,对Oracle多表查询优化的相关实际应用不是很了解的话,以下的文章会给你提供更全面的知识。以下就是文章的详细内容的介绍,望你会有所了解。

Oracle采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾.

例如:

(低效,执行时间156.3秒)

  1. SELECT …
  2. FROM EMP E
  3. WHERE SAL >; 50000
  4. AND JOB = ‘MANAGER’
  5. AND 25 < (SELECT COUNT(*) FROM EMP
  6. WHERE MGR=E.EMPNO);

(高效,执行时间10.6秒)

  1. SELECT …
  2. FROM EMP E
  3. WHERE 25 < (SELECT COUNT(*) FROM EMP
  4. WHERE MGR=E.EMPNO)
  5. AND SAL >; 50000
  6. AND JOB = ‘MANAGER’;

重点关注3:SELECT子句中避免使用 ‘ * ‘ .重点关注

当你想在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用 ‘*’ 是一个方便的方法.不幸的是,这是一个非常低效的方法. 实际上,Oracle在解析的过程中, 会将’*’ 依次转换成所有的列名, 这个工作是通过Oracle多表查询数据字典完成的, 这意味着将耗费更多的时间.

7. 减少访问数据库的次数

当执行每条SQL语句时, Oracle在内部执行了许多工作: 解析SQL语句, 估算索引的利用率, 绑定变量 , 读数据块等等. 由此可见, 减少访问数据库的次数 , 就能实际上减少Oracle的工作量.

例如,

以下有三种方法可以检索出雇员号等于0342或0291的职员.

方法1 (最低效)

  1. SELECT EMP_NAME , SALARY , GRADE
  2. FROM EMP
  3. WHERE EMP_NO = 342;
  4. SELECT EMP_NAME , SALARY , GRADE
  5. FROM EMP
  6. WHERE EMP_NO = 291;

方法2 (次低效)

  1. DECLARE
  2. CURSOR C1 (E_NO NUMBER) IS
  3. SELECT EMP_NAME,SALARY,GRADE
  4. FROM EMP
  5. WHERE EMP_NO = E_NO;
  6. BEGIN
  7. OPEN C1(342);
  8. FETCH C1 INTO …,..,.. ;
  9. OPEN C1(291);
  10. FETCH C1 INTO …,..,.. ;
  11. CLOSE C1;
  12. END;

以上的相关内容就是对Oracle多表查询优化的介绍,望你能有所收获。

推荐阅读
  • 数据库多表联合查询:内连接与外连接详解
    在数据库的多表查询中,内连接和外连接是两种常用的技术手段。内连接用于检索多个表中相互匹配的记录,即只有当两个表中的记录满足特定的连接条件时,这些记录才会被包含在查询结果中。相比之下,外连接则不仅返回匹配的记录,还可以选择性地返回不匹配的记录,具体取决于左外连接、右外连接或全外连接的选择。本文将详细解析这两种连接方式的使用场景及其语法结构,帮助读者更好地理解和应用多表查询技术。 ... [详细]
  • 提升Android开发效率:Clean Code的最佳实践与应用
    在Android开发中,提高代码质量和开发效率是至关重要的。本文介绍了如何通过Clean Code的最佳实践来优化Android应用的开发流程。以SQLite数据库操作为例,详细探讨了如何编写高效、可维护的SQL查询语句,并将其结果封装为Java对象。通过遵循这些最佳实践,开发者可以显著提升代码的可读性和可维护性,从而加快开发速度并减少错误。 ... [详细]
  • 如何高效地安装并配置 PostgreSQL 数据库系统?本文将详细介绍从下载到安装、配置环境变量、初始化数据库、以及优化性能的全过程,帮助读者快速掌握 PostgreSQL 的核心操作与最佳实践。文章还涵盖了常见问题的解决方案,确保用户在部署过程中能够顺利解决遇到的各种挑战。 ... [详细]
  • 在使用 SQL Server 时,连接故障是用户最常见的问题之一。通常,连接 SQL Server 的方法有两种:一种是通过 SQL Server 自带的客户端工具,例如 SQL Server Management Studio;另一种是通过第三方应用程序或开发工具进行连接。本文将详细分析导致连接故障的常见原因,并提供相应的解决策略,帮助用户有效排除连接问题。 ... [详细]
  • SSAS入门指南:基础知识与核心概念解析
    ### SSAS入门指南:基础知识与核心概念解析Analysis Services 是一种专为决策支持和商业智能(BI)解决方案设计的数据引擎。该引擎能够为报告和客户端应用提供高效的分析数据,并支持在多维数据模型中构建高性能的分析应用。通过其强大的数据处理能力和灵活的数据建模功能,Analysis Services 成为了现代 BI 系统的重要组成部分。 ... [详细]
  • 在使用SSH框架进行项目开发时,经常会遇到一些常见的问题。例如,在Spring配置文件中配置AOP事务声明后,进行单元测试时可能会出现“No Hibernate Session bound to thread”的错误。本文将详细探讨这一问题的原因,并提供有效的解决方案,帮助开发者顺利解决此类问题。 ... [详细]
  • 二十六、Java开发实战:PL/SQL轻松实现远程数据库连接
    通过 PL/SQL Developer 实现远程数据库连接的详细步骤如下:首先启动 PL/SQL Developer 软件,然后在登录界面中准确输入用户名和密码;接着在数据库连接配置中,按照 IP:Port/SID 的格式填写目标数据库的地址信息。此外,确保网络环境畅通无阻,并检查防火墙设置以避免连接失败。 ... [详细]
  • 在Node.js中调用MySQL存储过程`updateUser(p1, p2, @p3)`时,其中`@p3`为输出参数。若更新操作失败,则返回0;成功则返回1。本文将详细介绍如何正确获取存储过程的返回结果,并确保在实际应用中能够顺利执行。 ... [详细]
  • 深入解析数据库中的存储过程与触发器技术
    本文深入探讨了数据库中的存储过程与触发器技术。存储过程是一组预编译的SQL语句,经过优化后存储在数据库服务器中,以提高执行效率。在大型数据库系统中,通过调用存储过程的名字,用户可以快速执行复杂的操作,从而提升系统的性能和响应速度。此外,触发器作为一种特殊的存储过程,能够在特定事件发生时自动执行,进一步增强了数据库的自动化管理和数据完整性。 ... [详细]
  • 深入解析MySQL中的回表查询与索引覆盖技术
    在MySQL中,回表查询与索引覆盖技术是优化查询性能的重要手段。回表查询是指当使用非聚集索引进行查询时,由于非聚集索引的B-Tree叶子节点中仅存储了对应行数据的主键值,因此需要通过主键再次访问聚簇索引来获取完整数据记录。而索引覆盖则是在查询所需的所有列都包含在某个索引中,从而避免了额外的回表操作,显著提高了查询效率。本文将深入探讨这两种技术的原理及其应用场景,帮助读者更好地理解和优化MySQL查询性能。 ... [详细]
  • 如何使用mysql_nd:Python连接MySQL数据库的优雅指南
    无论是进行机器学习、Web开发还是爬虫项目,数据库操作都是必不可少的一环。本文将详细介绍如何使用Python通过 `mysql_nd` 库与 MySQL 数据库进行高效连接和数据交互。内容涵盖以下几个方面: ... [详细]
  • Spring框架的核心组件与架构解析 ... [详细]
  • 本文详细探讨了MySQL数据库实例化参数的优化方法及其在实例查询中的应用。通过具体的源代码示例,介绍了如何高效地配置和查询MySQL实例,为开发者提供了有价值的参考和实践指导。 ... [详细]
  • PostgreSQL 与 MySQL 的主要差异及应用场景分析
    本文详细探讨了 PostgreSQL 和 MySQL 在架构、性能、功能以及适用场景方面的关键差异。通过对比分析,帮助读者更好地理解两种数据库系统的特性和优势,为实际应用中的选择提供参考。 ... [详细]
  • 七款高效编辑器与笔记工具推荐:KindEditor自动换行功能解析
    本文推荐了七款高效的编辑器与笔记工具,并详细解析了KindEditor的自动换行功能。其中,轻笔记QingBiJi是一款完全免费的记事本软件,用户可以通过其简洁的界面和强大的功能轻松记录和管理日常事务。此外,该软件还支持多平台同步,确保用户在不同设备间无缝切换。 ... [详细]
author-avatar
拾味馆南湖店微博_328
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有