SQL语句的结构不会强制数据库先执行innert query。举个栗子,数据库可能会将整个语句重写为 employees和departments的join,那么这样的话 这个子查询将永远不会单独执行。另外一个例子,Virtual Private Database(VPD)特性可能会使用一个WHERE来对员工表的访问进行限制,这样,数据库可能决定首先查询employees,然后获取departments ID。优化器来决定获取需要行的最佳步骤
隐式查询(implicit qery)是DML语句的一个组件,帮助DML语句不使用子查询也能检索数据。一个UPDATE,DELETE,或MERGE语句,它们都不会显示包含SELECT语句,它们用隐式查询来检索要修改的行。举个例子,下面语句包含了一个找Baer记录的隐式查询:
UPDATE employees
SETsalary = salary*1.1
WHERElast_name = 'Baer';
唯一一个DML语句 查询组件不是必须的,那就是INSERT语句。举个例子,一个INSERT INTO TABLE mytable VALUES(1) 语句 不需要在插入行之前先检索行
Transaction ControlStatements(事务控制语句)
事务控制语句管理着 事务中DML语句及一组DML语句 造成的修改。这些语句使你可以:
·使事务中做的修改永久成效(COMMIT)
·将一个事务所做的修改回滚,回滚到事务开始之前(ROLLBACK),或回滚到savepoint(ROLLBACK TO SAVEPOINT)。一个savepoint是一个事务内容中用户申明的中间标记
注意:ROLLBACK语句会结束一个事务。但是ROLLBACK TO SAVEPOINT不会。
·设置一个你可以回滚的点(SAVEPOINT)
·设定一个事务的属性(SET TRANSACTION)
·指定一个可延迟的完整性约束,是在每个DML语句后检查,还是当事务提交时再检查(SET CONSTRAINT)。
下面例子开启了一个叫Update salaries的事务,这个例子创建了一个savepoint,更行了一个雇员的工资,然后回滚这个事务到savepoint。这个例子更新工资为一个其他值,然后提交。
SET TRANSACTION NAME 'Update salaries';
SAVEPOINT before_salary_update;
UPDATE employees SET salary=9100 WHEREemployee_id=1234 # DML
ROLLBACK TO SAVEPOINT before_salary_update;
UPDATE employees SET salary=9200 WHEREemployee_id=1234 # DML
COMMIT COMMENT 'Updated salaries';
Session Control Statements(Session控制语句)
Session控制语句动态管理 用户session的属性。像“Connections and Sessions”里解释的一样,一个session是数据库instance中的一个逻辑实体,它表示当前用户登录连接到一个数据库的状态。一个session从一个用户通过数据库的验证,一直持续到用户disconnect或exit。
Session控制语句可以让你:
·通过执行一个特殊的功能,来修改当前会话,比如开启和关闭SQL跟踪(ALTER SESSION)
·开启或关闭属于本用户的roles(角色),角色是一组权限(SET ROLE)
下面的例子,就是开启SQL跟踪,然后开启除了dw_mnager以外,授予当前session的所有角色:
ALTER SESSION SET SQL_TRACE = TRUE;
SET ROLE ALL EXCEPT dw_manager;
会话控制语句不会隐式提交当前会话
System Control Statements(系统控制语句)
系统控制语句更改数据库实例的特性。只有系统控制语句是ALTER SYSEM。它使你可以改变设置,如shared server的最小数量,停止一个session,以及其他系统级别的任务。
下面是系统控制语句的例子:
ALTER SYSTEM SWITCH LOGFILE;
ALTER SYSTEM KILL SESSION '39, 23';
ALTER SYSTEM语句不会隐式提交当前事务。
Embedded SQL Statements(嵌入式SQL语句)
嵌入式SQL语句,将DDL,DML,以及事务控制语句混入过程化语言程序。它们和Oracle预编译器 一起使用。嵌入式SQL是一种在过程化语句中包含SQL的一种方法。其他方法就是用程序化API(应用接口)比如 Open Database Connectivity(ODBC)或 Java Database Connectivity(JDBC)
嵌入式SQL语句可以使你:
·定义,分配,释放cursors(DECLARE CURSOR,OPEN,CLOSE)
·指定一个数据库,然后连接它(DECLARE DATABASE,CONNECT)
·分配变量名称(DECLARE STATEMENT).
·初始化描述符(DESCRIBE)
·指定错误和警告要怎样处理(WHENEVER)
·解析和运行SQL语句(PREPARE,EXECUTE,EXECUTE IMMEDIATE)
·从数据库获取数据(FETCH)
Overview of the Optimizer(优化器概述)
为了理解Oracle数据库是如何处理SQL语句的,那么必须要先理解什么是优化器(同样称之为query optimizer[查询优化器]或cost-based optimizer[基于成本的优化器]).所有的SQL语句都使用优化器来决定访问指定数据时最效率的方法。
Use of the Optimizer(优化器的使用)
为了执行一个DML语句,Oracle数据库可能要执行很多步骤。这些步骤,要么是从database中把物理数据检索出来,要么就是准备好数据为用户执行的语句。
经常会有还能多不同的路线来处理一个DML语句。举个例子,访问这些表,或索引的顺序可以变化。数据库用来执行一个语句的步骤很大程度上影响了这个语句运行有多快。优化器产生一堆执行计划,描述有多少种可能的执行方法。
优化器根据考虑多种信息资源,包括查询条件,可用执行路径,系统状态收集,以及Hints来决定采用哪个最优效率的执行计划。
Oracle处理任何SQL语句,优化器都会执行下面操作:
·表达式和条件的评估
·检查完整性约束来了解数据,以及基于这些元数据的优化
·语句转换
·优化器目标的选择
·访问路径的选择
·join顺序的选择。
优化器处理一个查询会产生非常多的路线,对于产生的每个执行计划中的每一步骤,都会分配一个cost(代价)。 最低成本的执行计划将被选择作为 查询计划,然后执行它。
注意:你可以获取一个执行计划,但不一定需要执行它。只有数据库实际用来执行一个查询的执行计划,才称之为