`

sql性能调整3 - 背景知识

 
阅读更多

第5章 ORACLE的执行计划


背景知识:
为了更好的进行下面的内容我们必须了解一些概念性的术语:


共享sql语句
为了不重复解析相同的SQL语句(因为解析操作比较费资源,会导致性能下降),在第一次解析之后,ORACLE将SQL语句及解析后得到的执行计划存放在内存中。这块位于系统全局区域SGA(system global area)的共享池(shared buffer pool)中的内存可以被所有的数据库用户共享。因此,当你执行一个SQL语句(有时被称为一个游标)时,如果该语句和之前的执行过的某一语句完全相同,并且之前执行的该语句与其执行计划仍然在内存中存在,则ORACLE就不需要再进行分析,直接得到该语句的执行路径。ORACLE的这个功能大大地提高了SQL的执行性能并大大节省了内存的使用。使用这个功能的关键是将执行过的语句尽可能放到内存中,所以这要求有大的共享池(通过设置shared buffer pool参数值)和尽可能的使用绑定变量的方法执行SQL语句。


当你向ORACLE 提交一个SQL语句,ORACLE会首先在共享内存中查找是否有相同的语句。这里需要注明的是,ORACLE对两者采取的是一种严格匹配,要达成共享,SQL语句必须完全相同(包括空格,换行等)。


下面是判断SQL语句是否与共享内存中某一SQL相同的步骤:
1). 对所发出语句的文本串进行hashed。如果hash值与已在共享池中SQL语句的hash值相同,则进行第2步:


2) 将所发出语句的文本串(包括大小写、空白和注释)与在第1步中识别的所有
已存在的SQL语句相比较。
例如:
SELECT * FROM emp WHERE empno = 1000;
和下列每一个都不同
SELECT * from emp WHERE empno = 1000;
SELECT * FROM EMP WHERE empno = 1000;
SELECT * FROM emp WHERE empno = 2000;
在上面的语句中列值都是直接SQL语句中的,今后我们将这类sql成为硬编码SQL
或字面值SQL
使用绑定变量的SQL语句中必须使用相同的名字的绑定变量(bind variables) ,
例如:
a. 该2个sql语句被认为相同
select pin , name from people where pin = :blk1.pin;
select pin , name from people where pin = :blk1.pin;
b. 该2个sql语句被认为不相同
select pin , name from people where pin = :blk1.ot_ind;
select pin , name from people where pin = :blk1.ov_ind;
今后我们将上面的这类语句称为绑定变量SQL。


3). 将所发出语句中涉及的对象与第2步中识别的已存在语句所涉及对象相比较。
例如:
如用户user1与用户user2下都有EMP表,则
用户user1发出的语句:SELECT * FROM EMP; 与
用户user2发出的语句:SELECT * FROM EMP; 被认为是不相同的语句,
因为两个语句中引用的EMP不是指同一个表。
4). 在SQL语句中使用的捆绑变量的捆绑类型必须一致。
如果语句与当前在共享池中的另一个语句是等同的话,Oracle并不对它进行语法分析。而直接执行该语句,提高了执行效率,因为语法分析比较耗费资源。
注意的是,从oracle 8i开始,新引入了一个CURSOR_SHARING参数,该参数的主要目的就是为了解决在编程过程中已大量使用的硬编码SQL问题。因为在实际开发中,很多程序人员为了提高开发速度,而采用类似下面的开发方法:
str_sql string;
int_empno int;
int_empno = 2000;
str_sql = ‘SELECT * FROM emp WHERE empno = ‘ + int_empno;
…………
int_empno = 1000;
str_sql = ‘SELECT * FROM emp WHERE empno = ‘ + int_empno;


上面的代码实际上使用了硬编码SQL,使我们不能使用共享SQL的功能,结果是数据库效率不高。但是从上面的2个语句来看,产生的硬编码SQL只是列值不同,其它部分都是相同的,如果仅仅因为列值不同而导致这2个语句不能共享是很可惜的,为了解决这个问题,引入了CURSOR_SHARING参数,使这类问题也可以使用共享SQL,从而使这样的开发也可以利用共享SQL功能。听起来不错,ORACLE真为用户着想,使用户在不改变代码的情况下还可以利用共享SQL的功能。真的如此吗?天上不会无缘无故的掉一个馅饼的,ORACLE对该参数的使用做了说明,建议在经过实际测试后再改该参数的值(缺省情况下,该参数的值为EXACT,语句完全一致才使用共享SQL)。因为有可能该变该值后,你的硬编码SQL是可以使用共享SQL了,但数据库的性能反而会下降。 我在实际应用中已经遇到这种情况。所以建议编写需要稳定运行程序的开发人员最好还是一开始就使用绑定变量的SQL。

 

Rowid的概念:
rowid是一个伪列,既然是伪列,那么这个列就不是用户定义,而是系统自己给加上的。对每个表都有一个rowid的伪列,但是表中并不物理存储ROWID列的值。不过你可以像使用其它列那样使用它,但是不能删除改列,也不能对该列的值进行修改、插入。一旦一行数据插入数据库,则rowid在该行的生命周期内是唯一的,即即使该行产生行迁移,行的rowid也不会改变。


为什么使用ROWID
rowid对访问一个表中的给定的行提供了最快的访问方法,通过ROWID可以直接定位到相应的数据块上,然后将其读到内存。我们创建一个索引时,该索引不但存储索引列的值,而且也存储索引值所对应的行的ROWID,这样我们通过索引快速找到相应行的ROWID后,通过该ROWID,就可以迅速将数据查询出来。这也就是我们使用索引查询时,速度比较快的原因。
在ORACLE8以前的版本中,ROWID由FILE 、BLOCK、ROW NUMBER构成。随着oracle8中对象概念的扩展,ROWID发生了变化,ROWID由OBJECT、FILE、BLOCK、ROW NUMBER构成。利用DBMS_ROWID可以将rowid分解成上述的各部分,也可以将上述的各部分组成一个有效的rowid。


Recursive SQL概念
有时为了执行用户发出的一个sql语句,Oracle必须执行一些额外的语句,我们将这些额外的语句称之为'recursive calls'或'recursive SQL statements'。如当一个DDL语句发出后,ORACLE总是隐含的发出一些recursive SQL语句,来修改数据字典信息,以便用户可以成功的执行该DDL语句。当需要的数据字典信息没有在共享内存中时,经常会发生Recursive calls,这些Recursive calls会将数据字典信息从硬盘读入内存中。用户不比关心这些recursive SQL语句的执行情况,在需要的时候,ORACLE会自动的在内部执行这些语句。当然DML语句与SELECT都可能引起recursive SQL。简单的说,我们可以将触发器视为recursive SQL。


Row Source(行源)
用在查询中,由上一操作返回的符合条件的行的集合,即可以是表的全部行数据的集合;也可以是表的部分行数据的集合;也可以为对上2个row source进行连接操作(如join连接)后得到的行数据集合。


Predicate(谓词)
一个查询中的WHERE限制条件


Driving Table(驱动表)
该表又称为外层表(OUTER TABLE)。这个概念用于嵌套与HASH连接中。如果该row source返回较多的行数据,则对所有的后续操作有负面影响。注意此处虽然翻译为驱动表,但实际上翻译为驱动行源(driving row source)更为确切。一般说来,是应用查询的限制条件后,返回较少行源的表作为驱动表,所以如果一个大表在WHERE条件有有限制条件(如等值限制),则该大表作为驱动表也是合适的,所以并不是只有较小的表可以作为驱动表,正确说法应该为应用查询的限制条件后,返回较少行源的表作为驱动表。在执行计划中,应该为靠上的那个row source,后面会给出具体说明。在我们后面的描述中,一般将该表称为连接操作的row source 1。


Probed Table(被探查表)
该表又称为内层表(INNER TABLE)。在我们从驱动表中得到具体一行的数据后,在该表中寻找符合连接条件的行。所以该表应当为大表(实际上应该为返回较大row source的表)且相应的列上应该有索引。在我们后面的描述中,一般将该表称为连接操作的row source 2。


组合索引(concatenated index)
由多个列构成的索引,如create index idx_emp on emp(col1, col2, col3, ……),则我们称idx_emp索引为组合索引。在组合索引中有一个重要的概念:引导列(leading column),在上面的例子中,col1列为引导列。当我们进行查询时可以使用”where col1 = ? ”,也可以使用”where col1 = ? and col2 = ?”,这样的限制条件都会使用索引,但是”where col2 = ? ”查询就不会使用该索引。所以限制条件中包含先导列时,该限制条件才会使用该组合索引。


可选择性(selectivity):
比较一下列中唯一键的数量和表中的行数,就可以判断该列的可选择性。如果该列的”唯一键的数量/表中的行数”的比值越接近1,则该列的可选择性越高,该列就越适合创建索引,同样索引的可选择性也越高。在可选择性高的列上进行查询时,返回的数据就较少,比较适合使用索引查询。

 

分享到:
评论

相关推荐

    SQL Server 2017 查询性能调优

    ### SQL Server 2017 查询性能调优知识点 #### 查询性能调优的必要性 在硬件性能不断提升的同时,查询性能调优依然是数据库维护和开发的重要方面。这是因为即便在硬件性能大幅提高的背景下,查询性能问题依然可能...

    SQL-Server-2008实用案例教程

    ### SQL Server 2008 实用案例教程知识点解析 #### 一、数据库技术概览 **1.1 数据库技术** - **定义**: 数据库技术是计算机科学的一个分支,专注于设计、实施和管理用于存储、组织和检索数据的系统。在当前信息...

    泛微系统SQL语句大全

    以下是对这些SQL语句知识点的详细解释: 1. **组织架构相关SQL**: - 组织架构是企业信息化管理的基础,SQL语句可用于查询、更新和维护组织结构,例如部门、职位、员工信息等。例如,你可以使用`SELECT`语句来获取...

    高级owi与oracle性能调整

    根据给定的信息,“高级owi与oracle性能调整”这本书聚焦于Oracle数据库性能优化及owi(Online Workload Identification,即在线工作负载识别)相关的技术探讨。由于提供的具体内容中并未包含实际的技术内容,以下的...

    Oracle 调优指南

    - **自动SQL调整**:Oracle提供了自动化工具来帮助识别和解决SQL性能问题。 - **自动调整优化器**:Oracle自动调整优化器能够根据系统负载和资源使用情况自动调整优化策略。 - **统计数据分析**:利用统计数据分析...

    ORACLE SQL的性能优化

    ##### 背景知识 在探讨Oracle SQL性能优化之前,首先需理解Oracle处理SQL语句的基本流程,这是提升性能的关键所在。Oracle SQL的执行过程大致分为以下几个阶段: - **查询语句处理** - **DML语句处理**(Insert, ...

    oracle SQL 对比.doc

    ### Oracle SQL 与 MSSQL Server 7.0 迁移中的关键知识点 #### 一、迁移背景与目标 - **目的**: 本文旨在帮助具备Oracle经验的开发人员将其应用程序迁移至Microsoft SQL Server环境,尤其针对SQL Server 7.0版本。...

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

    #### 一、性能调整综述 - **调整的重要性**: - Oracle数据库具备高度可调性,合理的调整能够显著提升性能。 - 调整不仅局限于数据库层面,还涉及到操作系统、硬件及软件配置等。 - **调整参与人员**: - **...

    The Art of SQL中文版

    ### SQL语言艺术:掌握SQL性能的关键 #### 一、引言与背景 随着信息技术的快速发展,数据处理成为了现代系统的核心。在过去,数据处理被称为“电子数据处理”,而在今天,随着数据量的快速增长,数据处理的重要性...

    NCR_teradata_SQL执行分析

    - 在实际应用中,需要不断调整SQL语句以适应数据变化。 - 定期对SQL语句进行性能分析,查找瓶颈所在。 - 使用Teradata提供的工具和技术进行调优。 #### 四、SQL执行分析案例 以下是一个具体的SQL执行分析案例,...

    SQLServer2008查询性能优化 2/2

    第1章 SQL查询性能调整 1 1.1 性能调整过程 2 1.1.1 核心过程 2 1.1.2 迭代过程 4 1.2 性能vs.价格 7 1.2.1 性能目标 7 1.2.2 “足够好”的调整 7 1.3 性能基线 8 1.4 工作的重点 9 1.5 SQL Server性能杀手...

    SQLServer2008查询性能优化 1/2

    第1章 SQL查询性能调整 1 1.1 性能调整过程 2 1.1.1 核心过程 2 1.1.2 迭代过程 4 1.2 性能vs.价格 7 1.2.1 性能目标 7 1.2.2 “足够好”的调整 7 1.3 性能基线 8 1.4 工作的重点 9 1.5 SQL Server性能杀手...

    自我管理数据库-自动的sql调优

    因此,我将基于标题和描述中的关键词来展开相关知识点,并结合Linux命令的部分内容作为背景信息。 ### 自我管理数据库-自动的SQL调优 #### 一、自我管理数据库简介 自我管理数据库是指能够自动完成常规管理和维护...

Global site tag (gtag.js) - Google Analytics