`
eksliang
  • 浏览: 599028 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

ORACLE 复习笔记之SQL语句的优化

阅读更多

转载请出自出处:http://eksliang.iteye.com/blog/2097999

  SQL语句的优化总结如下

 

sql语句的优化可以按照如下六个步骤进行:

  1. 合理使用索引
  2. 避免或者简化排序
  3. 消除对大表的扫描
  4. 避免复杂的通配符匹配
  5. 调整子查询的性能
  6. EXISTS和IN运算符

下面我就按照上面这六个步骤分别进行总结:

  • 1-------------------------------------合理使用索引

  首先要明确创建索引的根本目的是:提高查询效率;

  使用原则如下:

1.1、在条件表达式中经常用到的不同值较多的列上建立索引

1.2、在不值少的列上不要创建索引,或者位图索引

      例如:在员工表的性别列上,只有“男”和“女”两个不同值,如果建立索引,不但不会提高性能

1.3、在经常进行连接,但是没有指定为外键的列上建立索引

      根据我的经验,在实际开发中,数据库的设计是不会建立索引的,都是通过在外键上面建立索引进行关联,这样性能更好;

1.4.在频繁进行排序或分组的列上建立索引

1.5.如果待排序的列有多个,可以建立组合索引

         例如:order by D,E 那要注意:在建立索引时,注意D列和E列和排序后面的顺序要相同,不然不管是那种数据库都不会用到这个索引;

1.6.如果条件表达式中经常对某个列应用某个函数后指定查询条件,则应建立函数索引

备注:对于Oracle中怎样建立索引,有多少索引,以及应用场景,在接下来的帖子中我会加进来

 

  • 使用索引需要注意的地方

 下面情况的SQL,不会用到列上的索引,应尽量避免使用:

 1.  存在数据类型的隐形转换时,例如

 

select * from emp where empno = ‘7369’;

 

    注意上面的empno列是number类型的,这样转化就不会用到这个索引

 

2. 列上有数学运算时,例如

 

Select * from emp where sal*2 <1000;

 

  这是因为在索引上只有sal的值,没有sal*2的值,应该改成

 

select * from emp where sal<1000/2 ;

 

 

 3.使用不等于(<>)运算时 例如

 

 

Select * from emp where deptno <>10;

 

 4.使用substr字符串函数时,例如

 

 

Select * from emp where substr(ename,1,3)=‘SMI’;
 5.‘%’通配符在第一个字符时,例如

 

 

Select * from emp where ename like’%th’;

 

 6.字符串连接( || )时,例如

 

 

Select * from emp where ename || ‘abc’ = ‘SMITHabc’;

 

 

 

 

  • 2-------------------------------------避免或者简化排序

2.1 应当简化或避免对大型表进行重复的排序,以下情况,oracle是会默认对他排序的情况

  • SQL中包含Group By子句
  • SQL中包含Order By子句
  • SQL中包含Distinct子句
  • SQL中包含Minus或Union子句
  • in子句中的SQL子查询

2.2 以下情况不能有效地利用索引

1.待排序列没有全部建立索引,例如

 

order by D,E 而在表中只在D列上创建了索引
Group by 或者 Order by 子句中列的顺序与索引的列的顺序不同
 2.连接查询时排序的列来自不同的表(索引不能跨表)

 

 避免或简化排序的总结如下:为了避免不必要的排序,就要正确地增建索引,合理地合并数据库表。如果排序不可避免,那么应当试图简化它,如缩小排序的列的范围等

 

 

  • 3-------------------------------------消除对大表的扫描

3.1. 在连接查询中,对表的顺序存取可能对查询效率产生致命的影响。避免这种情况的主要方法就是对连接的列进行索引。例如有两个表,学生表(学号、姓名、年龄…)和选课表(学号、课程号、成绩)。如果两个表要做连接,就要在”学号”这个连接字段上建立索引。

 

 

3.2 使用并集来避免顺序存取。尽管在所有的检查列上都有索引,但某些形式的 where 子句强迫数据库使用顺序存取。例如

 

Select * from abc where a>10 or b<10;

 

       尽管我们在B和C列上都建立了索引,但是在上面语句中,优化器还是使用顺序存取方式扫描整个表。因为这个语句要检索的是分离的行的集合,可改为如下语句

 

 

Select * from abc where a>10
Union
Select * from abc where b<10

 

 

 

  • 4-------------------------------------避免困难的通配符匹配

复杂的通配可能导致耗时的查询。例如

 

Select * from customer where zipcode like ’98_ _ _’;

 

 即使在zipcode字段上建立了索引,在这种情况下也还是采用顺序扫描的方式。应改成

 

 

Select * from customer 
where zipcode >=’98000’ and zipcode <‘ 99000’

 

 

 

 

  • 5-------------------------------------调整子查询的性能

子查询包括两种,关联子查询、非关联子查询,下面分别对这两种进行分析

5.1 非关联子查询

       非关联子查询时子查询只会执行一次,而且结果集是已经排序完毕的,并保存在一个Oracle的临时段中,其中的每一个记录在返回时都会被父查询所引用。在子查询返回大量记录的情况下,将这些结果集排序,以及将临时数据段进行排序会增加大量的系统开销。例如

 

select emp_name from emp_number where emp_id in (select emp_id from emp_func);

 

 

 

5.2 关联子查询

解释一下,什么是关联子查询,就是子查询中的条件用到了父查询中的列,例如:

select emp_name from emp_number where emp_id in (select emp_id from emp_func where emp_number.emp_id = emp_func.emp_id);

 

      对返回到父查询的记录来说,子查询会每行执行一次。因此必须保证子查询尽可能用到索引。关联子查询的系统开销更高。

 对于子查询我的应用原则就是:查询嵌套的层次越多,效率越低,因此应当尽量避免子查询。如果子查询不可避免,那以要在子查询中过滤掉尽可能多的行。

 

  • 6-------------------------------------EXISTS和IN运算符

6.1 带IN的关联子查询是多余的,因为IN子句和子查询中相关操作的功能是一样的。例如

Select emp_name from emp_member where emp_id in (select emp_id from emp_func where emp_member.emp_id = emp_func.emp_id);

 

 

6.2 为非关联子查询指定EXISTS子句是不适当的,因为这样会产生笛卡尔积)。例如

Select emp_name from emp_member
Where exists(select emp_id from emp_func);

 

 

6.3 尽量不要使用NOT IN 子句,虽然使用MINUS子句要进行两次查询,使用MINUS子句依然比 NOT IN 子句快,这种情况你应该这么写

Select emp_name from emp_member where emp_id 
in (select  emp_id from emp_member 
minus 
Select emp_id from emp_func where func_id like ’81%’ );

 

 

 

 

最后测试索引的性能,下面这个例子是在网上看到的,我直接拿过来了,我觉得非常经典

1.新建dumpy表,然后向dumpy表中添加1000万行记录,其中ID列是有序的整数,Name是随机的字符串,Rand列是随机的数值

测试环境Oracle,创建表的语法如下:

create table dumpy
(
   id       number(10),
   name     varchar2(10),
   rand     number(10,2)
);

 

添加数据的语法如下:

declare
  recordcount integer := 10000000;  -- 1000万条记录
begin
  for i in 1..recordcount loop
    insert into dumpy(id, name, rand)
    values ( i, dbms_random.string('x', 8),
             abs(dbms_random.random) / 100.0);
    if mod(i, 1000) = 0 then
      commit;                          -- 每插入1000条提交
    end if;
  end loop;
end;

 数据添加成功后,查询Rand值介于1000到2000之间的行。添加索引,比较优化前后查询速度的变化。

  提示:执行命令 SET TIMING ON,可以显示每次语句执行时间

 

 

 

 

 

    

 

      

分享到:
评论

相关推荐

    ORACLE学习笔记之调节性能优化篇

    本文主要围绕ORACLE数据库的性能优化,特别是如何通过不同的方式来追踪和分析SQL语句的执行,从而找出性能瓶颈。 首先,了解如何查询当前正在执行语句的执行计划是至关重要的。通过`V$SQL_PLAN`视图,我们可以获取...

    oracle_sql笔记

    在Oracle中,事务是一组SQL语句,被视为一个工作单元。事务处理包括提交(COMMIT)、回滚(ROLLBACK)和保存点(SAVEPOINT),确保数据的一致性和完整性。 十、性能优化 Oracle提供了多种性能优化手段,如索引优化、查询...

    java笔记+sql语句

    10. **SQL语句**:SQL(Structured Query Language)是用于管理和处理关系数据库的标准语言。它包括数据查询、数据插入、数据更新和数据删除等操作。在Java中,可以通过JDBC(Java Database Connectivity)API来连接...

    oracle sql语句学习

    在"oracle笔记"中,你可能会看到对这些概念的详细解释,以及实际的示例代码和练习。学习时,建议先理解基本语法,然后通过实际操作来加深理解,最后通过解决实际问题来提高技能。记住,理论与实践相结合是成为SQL...

    oracle复习笔记03

    根据提供的文件信息,我们可以梳理出一系列关于Oracle数据库的重要知识点,主要涵盖了数据类型、PL/SQL控制结构、游标以及过程等内容。以下是对这些知识点的详细解释: ### 数据类型 1. **VARCHAR2** - `VARCHAR2...

    (转)最全的SQL(Oracle)笔记集录

    而“工具”可能指的是与Oracle数据库管理相关的实用工具,如SQL Developer或SQL*Plus,这些工具可以帮助用户更有效地编写和执行SQL语句。 【压缩包子文件的文件名称列表】:常用sql语句.tif 这个文件名表明压缩包...

    精通 ORACLE SQL高级编程 学习笔记

    精通Oracle SQL【第2版】ORACLE SQL高级编程【第二版】学习笔记

    oracle 9i pl/sql程序设计笔记

    ### Oracle 9i PL/SQL程序设计笔记精要 #### PL/SQL基础知识概览 **标题与描述**:本文档围绕“Oracle 9i PL/SQL程序设计笔记”这一核心主题,深入探讨了PL/SQL语言的基础知识及其在Oracle 9i数据库环境中的应用。...

    oracle优化笔记

    综上所述,Oracle优化不仅涉及SQL语句的优化,还包括PL/SQL编程技巧、系统函数与系统包的有效利用、DBA管理技能以及Oracle工具的应用等多个方面。掌握这些技术和方法有助于提高Oracle系统的性能和稳定性。

    java笔记\Oracle里sql不能用limit的处理

    Java笔记--Oracle中SQL不能用Limit的处理 在Java开发中,我们经常需要对数据库进行分页查询,但是Oracle数据库不支持Limit关键字,那么如何在Oracle中实现分页查询呢?下面,我们将详细介绍Oracle中SQL不能用Limit...

    Oracle常用SQL语句复习

    这篇“Oracle常用SQL语句复习”涵盖了在Oracle环境中经常使用的一些核心SQL语句,这对于数据库管理员和开发人员来说至关重要。 1. **数据查询**:在Oracle中,`SELECT`语句是最基础的查询工具。例如,`SELECT ...

    Oracle学习笔记 PDF

    - SQL语句本身不区分大小写,但在查询特定字段值时需要区分大小写。 ##### 3.2 记事本命令调用 - **编写SQL程序**: - 在编写多行SQL命令时,直到输入分号才会执行命令。 - 可以使用外部编辑器(如记事本)编写...

    Oracle SQL笔记.pdf

    根据提供的文件信息,我们可以归纳出一系列重要的...这些知识点覆盖了SQL的基础概念、查询语句、函数使用、多表查询、数据操纵、数据库设计、约束管理、事务控制等多个方面,对于学习和掌握Oracle SQL具有重要意义。

    韩顺平Oracle教学笔记.docx

    SQL语句是Oracle数据库中最基本的操作语言,包括select、insert、update和delete四种基本语句。select语句用于查询数据,insert语句用于添加数据,update语句用于修改数据,delete语句用于删除数据。 2. 数据类型:...

    oracle复习笔记01

    以上是对提供的“oracle复习笔记01”中涉及的关键知识点的总结与解释。这些知识点不仅涵盖了基础的SQL语句应用,还包括了更高级的数据处理和查询技术,对于初学者和有一定经验的Oracle用户来说都是非常有价值的参考...

    oracle实用笔记 命令 文档 pdf

    优化器决定了SQL语句的最佳执行路径,而索引、分区、物化视图等都是常用的性能优化手段。 8. **数据库架构**:理解Oracle的多租户架构,如单实例和容器数据库(CDB),以及PDB(Pluggable Database)的概念,有助于...

    Oracle学习笔记精华版

    笔记可能涉及索引的创建和管理、SQL调优(如使用EXPLAIN PLAN分析查询执行计划)、数据库统计信息的收集、存储优化以及使用Oracle的性能监控工具(如AWR和ASH报告)。 此外,Oracle的安全管理包括用户权限管理、...

    oracle复习笔记02

    - **说明**: SQL语句中的大小写敏感性取决于数据库的具体配置。 - **示例**: - `SELECT * FROM table WHERE xx = 'zhangsan';` - `SELECT * FROM table WHERE xx = 'ZHANGSAN';` - **解决方案**: 为了避免大小写...

    MLDN Oracle SQL语句集合

    这份笔记详细记录了在实际操作Oracle数据库时可能会遇到的各种SQL语句,旨在帮助用户提升对Oracle SQL的掌握程度。下面,我们将深入探讨其中的关键知识点。 一、SQL基础 SQL(Structured Query Language)是用于...

    SQL语句笔记

    - **SELECT语句**:最常用的SQL语句之一,用于从数据库中检索数据。 - `SELECT * FROM table WHERE a = ''`:这表示从`table`中选取所有列,但只返回那些`a`列值为空的行。 - 数据库对大小写敏感,而SQL语句本身则...

Global site tag (gtag.js) - Google Analytics