Oracle sql优化必知——表的访问

简介:

《访问数据的方法》

访问表中的数据有两种:1、直接访问表   2、先访问索引,再回表


1、直接访问表的两种方法:

①、全表扫描 

    全表扫描是指Oracle在访问目标表的数据时,会从该表所占用的第一个区(extent)的第一个块(block)开始扫描,一直扫描到该表的高水位线,这段范围内的所有数据库都必须读到,当然如果目标sql的where中指定的过滤条件,最后只返回满足条件的数据即可;(有时候全表扫描的效率还是非常高的,但是随着表的数据增多 资源消耗也会在逐步增加)


②、rowid扫描

    rowid扫描是指Oracle在访问目标表里的数据时,直接通过数据所在的rowid去定位并访问这些数据。rowid表示的是Oracle中的数据行记录所在的物理存储地址,也就是说rowid实际上是和Oracle中数据块里的行记录一一对应的。

    Oracle中的rowid扫描有两层含义:

    一种是根据用户在sql语句中输入的rowid的值直接访问对应的数据行记录;

    另一种是先去访问相关的索引,然后根据访问索引后得到的rowid再回表去访问对应的数据行记录。


2、访问索引的方法

   常用的是B树索引,优点如下:

   ①:所有的索引叶子块都在同一层,即他们距离索引根节点的深度是相同的,这也意味着访问索引叶子块的任何一个索引键值所花费的时间几乎相同。

   ②:Oracle会保证所有的B树索引都是自平衡的,即不可能出现不同的索引叶子块不处同一层的现象。

   ③:通过B树索引访问表里行记录的效率并不会随着相关表的数据量递增而显著降低,即通过走索引访问数据的时间是可控的,基本稳定的,这也是走索引和全表扫描的最大区别;

 

 一些常见的访问B树索引的方法:

 ①:索引唯一性扫描(index unique scan):

    索引唯一性扫描是针对唯一性索引的扫描,它仅适用于where条件里是等值查询的目标sql。因为扫描的对象是唯一性索引,所以索引唯一性扫描的结果至多只会返回一条记录。

 ②:索引范围扫描(index range scan)     

    索引范围扫描适用于所有类型的B树索引,当扫描的对象是唯一性索引时,此时目标sql的where条件一定是范围查询;要注意即使是针对同等条件下的相同的sql,当目标索引的数量大于1时,索引范围扫描所耗费的逻辑读会多于索引唯一性扫描所耗费的逻辑读。

 ③:索引全扫描(index full scan) 

    索引全扫描适用于所有类型的B树索引(包括唯一性索引和非唯一性索引)。是指要扫描目标索引所有叶子块的所有索引行。

    默认情况下,Oracle在做索引全扫描时只需要通过访问必要的分支块定位到位于该索引最左边的叶子块的第一行索引行;

    说明:索引全扫描的执行结果也是有序的,并且是按照该索引的索引键值列来排序,这也意味着走索引全扫描能够即达到排序的

    效果,又同时避免了该索引的索引键值列达的真正排序操作。

 ④:索引快速全扫描(index fast full scan)

    索引快速全扫描和索引全扫描极为类似,它也是由于所有类型的B树索引(包括唯一性索引和非唯一性索引)。和索引全扫描一样,索引快速全扫描也需要扫描目标索引所有叶子块的所有索引行;

索引快速全扫描与索引全扫描的区别如下:

    ①:索引快速全扫描只适用CBO

    ②:索引快速全扫描可以使用多块读,也可以并行执行

    ③:索引快速全扫描的执行结果不一定是有序的。

    

例句:如下带hint的目标sql是让Oracle走对主键索引pk_emp_test的索引快速全扫描

    (emp_test是表名   pk_emp_test是表的主键复合索引  empno是查询的字段)

    select /*+ index_ffs(emp_test pk_emp_test) */empno from emp_test;

 

 ⑤:索引跳跃式扫描(index skip scan)

   索引跳跃式扫描适用所有类型的复合B树索引(包括唯一性索引和非唯一性索引),它使那些在where条件中没有对目标索引的前导列指定查询条件

   但同时对该索引的非前导列指定了查询条件的sql依然可以用上该索引。

   

注意:

   Oracle中的索引跳跃式扫描仅适用于那些目标索引前导列的distinct值数量较少、后续非前导列的可选择性又非常好的图形,因为索引跳跃式扫描的执行

   效率一定会随着目标索引前导列的distinct值数量的递增而递减。     


清空数据字典缓:--生产库禁用

SQL> alter system flush shared_pool;

清空buffer cache缓存:---生产库禁用

SQL> alter system flush buffer_cache;


《表连接》

1、表连接顺序

   不管目标sql有多少个表做表连接,Oracle在实际执行该sql时都只能先两两做表连接,再一次执行这样的两两表连接过程,直到目标sql中所有的表都已经连接完毕;

   

2、表连接方法:

   两个表连接的方法有:排序合并连接、嵌套循环连接、哈希连接、笛卡尔积连接 四种;


3、表连接的类型:

 3.1内连接:

   内连接是指表连接的连接结果只包含那些完全满足连接条件的记录。对于包含表连接的目标sql而言,只要起where条件中没有写那些标准sql中定义或者Oracle中自定义的表示外连接的关键字(比如标准sql中的left outer join、right outer join、full outer join,或者Oracle中自定义的用来表示外连接的关键字“+”),则该sql的连接类型就是内连接。

   如: select t1.col1,t1.col2,t2.col3 from t1,t2 where t1.col2=t2.col2; 这条sql就没有那些关键字,这就是内连接

   标准sql中的内连接写法是用:join on   或  join using  (natural join 特殊的连接方法)

  

 join  on 语法:目标表1  join  目标表2  on  (连接条件)

       如:select t1.col1,t1.col2,t2.col3 from t1 join t2 on (t1.col2=t2.col2);

 

join  using 语法:目标表1  join  目标表2  using (连接列集合)

       如:select t1.col1,col2,t2.col3 from t1 join t2 using (col2);

注意:对于使用join using的标准sql而言,如果连接列同时又出现在查询列中,则该连接列前不能带上表名或者表名的别名,否则Oracle会报错(ORA-25154)

    

natural join语法:目标表1  natural  join  目标表2 

       如:select t1.col1,col2,t2.col3 from t1 natural join t2;

 

注意:

   对于内连接而言,除了表连接条件之外的额外限制条件在目标sql的sql文本中所处的位置并不会影响该sql的实际执行结果;


 3.2、外连接(outer join)

    外连接 是对内连接的一种扩展,它是指表连接的连接结果除了包含那些完全满足连接条件的记录之外还会包含驱动表中所有不满足该连接条件的记录。

    外连接分为:左连接(left outer join )  右连接(right outer join )和全连接(full outer join)

    

    左连接的语法:(关键字左边的就是驱动表,即目标表1就是驱动表)

      左连接的查询结果除了包含目标表1和目标表2中所有满足该连接条件的记录外,还包含驱动表中所有不满足该连接条件的记录,同时,驱动表中所有不满足该连接条件的记录所对应的被驱动表中的查询列均会以null值来填充。

    目标表1  left outer join  目标表2  on (连接条件)  或  目标表1  left outer join 目标表2  using (连接列集合)

    

    右连接的语法:(关键字右边的就是驱动表,即目标表2就是驱动表) 

       右连接的查询结果除了包含目标表1和目标表2中所有满足该连接条件的记录外,还包含驱动表中所有不满足该连接条件的记录,同时,驱动表中所有不满足该连接条件的记录所对应的被驱动表中的查询列均会以null值来填充。

    目标表1  right  outer join   目标表2  on (连接条件)  或  目标表1  right outer join 目标表2 using(连接列集合)

    

    全连接的语法:

    全连接的查询结果除了包含目标表1和目标表2中所有满足该连接条件的记录外,还包含目标表1和目标表2中所有不满足该连接条件的记录,同时,驱动表中所有不满足该连接条件的记录所对应的被驱动表中的查询列均会以null值来填充。

    目标表1  full outer join 目标表2 on (连接条件)  或  目标表1  full outer join 目标表2 using (连接列集合)

    

注意:

   对于外连接而言,除了表连接条件之外的额外限制条件在目标sql的sql文本中所处的位置确实可能会影响该sql的实际执行结果。

   Oracle自定义的关键字“(+)”来表示外连接:

      关键字“(+)”出现在哪个表的连接列后面,就表名哪个表会以null值来填充那些不满足连接条件并位于该表中的查询列,

      此时应该以关键字“(+)”对面的表来作为外连接的驱动表,这里的关键是决定哪个表是驱动表;


4、表连接的方法:

   在Oracle数据库中有四种表连接方法:排序合并连接、嵌套循环连接、哈希连接和笛卡尔连接      


4.1、排序合并连接(sort merge join)

    排序合并连接是一种两个表在做表连接时用排序操作(sort)和合并操作(merge)来得到连接结果集的表连接方法;

    

    排序合并连接的优缺点及适用场景:

    ①:通常情况下,排序合并连接的执行效率会远不如哈希连接,但前者的使用范围更广,因为哈希连接通常只能用于等值连接条件,

        而排序合并连接还能用于其他连接条件(例如:<  <=  >  >=)

    ②:通常情况下,排序合并连接并不适合OLTP类型的系统,因为对于OLTP类型的系统而言,排序是非常昂贵的操作,当然,如果能

        避免排序操作,那么即使是OLTP类型的系统,也还是可以使用排序合并连接的。

    ③:从严格意义上来说,排序合并连接并不存在驱动表的概念;

 

4.2嵌套循环连接(nested loops join)

   嵌套循环连接是一种两个表在做表连接时依靠两层嵌套循环(分别为外层循环和内层循环)来得到连接结果集的表连接方法。

   

   嵌套循环连接的优缺点及适用场景:

   ①:如果驱动表















本文转自一个笨小孩51CTO博客,原文链接: http://blog.51cto.com/fengfeng688/1953300,如需转载请自行联系原作者




相关文章
|
1月前
|
SQL 存储 监控
SQL日志优化策略:提升数据库日志记录效率
通过以上方法结合起来运行调整方案, 可以显著地提升SQL环境下面向各种搜索引擎服务平台所需要满足标准条件下之数据库登记作业流程综合表现; 同时还能确保系统稳健运行并满越用户体验预期目标.
180 6
|
2月前
|
SQL Oracle 关系型数据库
Oracle数据库创建表空间和索引的SQL语法示例
以上SQL语法提供了一种标准方式去组织Oracle数据库内部结构,并且通过合理使用可以显著改善查询速度及整体性能。需要注意,在实际应用过程当中应该根据具体业务需求、系统资源状况以及预期目标去合理规划并调整参数设置以达到最佳效果。
278 8
|
5月前
|
存储 Oracle 关系型数据库
Oracle存储过程插入临时表优化与慢查询解决方法
优化是一个循序渐进的过程,就像雕刻一座雕像,需要不断地打磨和细化。所以,耐心一点,一步步试验这些方法,最终你将看到那个让你的临时表插入操作如同行云流水、快如闪电的美丽时刻。
286 14
|
6月前
|
Oracle 关系型数据库 数据库
【赵渝强老师】在PostgreSQL中访问Oracle
本文介绍了如何在PostgreSQL中使用oracle_fdw扩展访问Oracle数据库数据。首先需从Oracle官网下载三个Instance Client安装包并解压,设置Oracle环境变量。接着从GitHub下载oracle_fdw扩展,配置pg_config环境变量后编译安装。之后启动PostgreSQL服务器,在数据库中创建oracle_fdw扩展及外部数据库服务,建立用户映射。最后通过创建外部表实现对Oracle数据的访问。文末附有具体操作步骤与示例代码。
231 6
【赵渝强老师】在PostgreSQL中访问Oracle
|
6月前
|
SQL 存储 自然语言处理
SQL的解析和优化的原理:一条sql 执行过程是什么?
SQL的解析和优化的原理:一条sql 执行过程是什么?
SQL的解析和优化的原理:一条sql 执行过程是什么?
|
8月前
|
SQL 关系型数据库 MySQL
如何优化SQL查询以提高数据库性能?
这篇文章以生动的比喻介绍了优化SQL查询的重要性及方法。它首先将未优化的SQL查询比作在自助餐厅贪多嚼不烂的行为,强调了只获取必要数据的必要性。接着,文章详细讲解了四种优化策略:**精简选择**(避免使用`SELECT *`)、**专业筛选**(利用`WHERE`缩小范围)、**高效联接**(索引和限制数据量)以及**使用索引**(加速搜索)。此外,还探讨了如何避免N+1查询问题、使用分页限制结果、理解执行计划以及定期维护数据库健康。通过这些技巧,可以显著提升数据库性能,让查询更高效流畅。
|
7月前
|
SQL Oracle 关系型数据库
解决大小写、保留字与特殊字符问题!Oracle双引号在SQL中的特殊应用
在Oracle数据库开发中,双引号的使用是一个重要但易被忽视的细节。本文全面解析了双引号在SQL中的特殊应用场景,包括解决标识符与保留字冲突、强制保留大小写、支持特殊字符和数字开头标识符等。同时提供了最佳实践建议,帮助开发者规避常见错误,提高代码可维护性和效率。
280 6
|
8月前
|
SQL Oracle 关系型数据库
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
|
8月前
|
SQL Oracle 关系型数据库
【YashanDB知识库】yashandb执行包含带oracle dblink表的sql时性能差
【YashanDB知识库】yashandb执行包含带oracle dblink表的sql时性能差
|
8月前
|
SQL Oracle 关系型数据库
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
本文来自YashanDB官网,介绍如何处理Oracle客户端sql*plus中使用@@调用同级目录SQL脚本的场景。崖山数据库23.2.x.100已支持@@用法,但旧版本可通过Python脚本批量重写SQL文件,将@@替换为绝对路径。文章通过Oracle示例展示了具体用法,并提供Python脚本实现自动化处理,最后调整批处理脚本以适配YashanDB运行环境。

推荐镜像

更多