SQL语句的执行顺序

来源:互联网 发布:python java go 编辑:程序博客网 时间:2024/05/04 13:35

sql语句的执行步骤:
1)语法分析,分析语句的语法是否符合规范,衡量语句中各表达式的意义。
2) 语义分析,检查语句中涉及的所有数据库对象是否存在,且用户有相应的权限。
3)视图转换,将涉及视图的查询语句转换为相应的对基表查询语句。
4)表达式转换, 将复杂的 SQL 表达式转换为较简单的等效连接表达式。
5)选择优化器,不同的优化器一般产生不同的“执行计划”
6)选择连接方式, ORACLE 有三种连接方式,对多表连接 ORACLE 可选择适当的连接方式。
7)选择连接顺序, 对多表连接 ORACLE 选择哪一对表先连接,选择这两表中哪个表做为源数据表。
8)选择数据的搜索路径,根据以上条件选择合适的数据搜索路径,如是选用全表搜索还是利用索引或是其他的方式。
9)运行“执行计划”

 

2、oracle 共享原理:
      ORACLE将执行过的SQL语句存放在内存的共享池(shared buffer pool)中,可以被所有的数据库用户共享 当你执行一个SQL语句(有时被称为一个游标)时,如果它和之前的执行过的语句完全相同, ORACLE就能很快获得已经被解析的语句以及最好的 执行路径. 这个功能大大地提高了SQL的执行性能并节省了内存的使用

 

3、SQL Select语句完整的执行顺序:
1)、from子句组装来自不同数据源的数据;
2)、where子句基于指定的条件对记录行进行筛选;
3)、group by子句将数据划分为多个分组;
4)、使用聚集函数进行计算;
5)、使用having子句筛选分组;
6)、计算所有的表达式;
7)、使用order by对结果集进行排序。

 

4、多表连接查询时顺序:
例如:
select * from a inner join b on a.bid=b.id inner join c on b.cid=c.id where a.XXX='XXX'
1)、from a、b、c作为数据源
2)、通过where a.XXX='XXX' 筛选a表里的数据
3)、a表与b表依次对比,根据on条件,筛选符合条件的数据集
4)、将a、b两张表得到的结果集再和c中的记录依次对比,筛选符合条件的数据集
5)、完成
注意:
在多表关联查询时,哪两个表先结合查询,要通过优化器的分析,走CBO模式,一般将数据多的放在里面,数据少的放在外面。这里是假定排序是a、b、c。

--------------------------------------------------------------------------------------------------------------

SQL处理过程:

OPERATION

PURPOSE

OPEN

Allocate memory for data structures.

PARSE

check syntax,genetate parse tree,check privileges,and create execution plan.Allocate private SQL area.Allcote shared SQL area.

DESCRIBE

Return the types and length of query select list columns.Only required for queries provided by an alllication at run time.

DEFINE

Define program memory location,type,and size of variables for select list columns.

BIND

Specify the memory location and value of bind variables.

EXECUTE

Execute the statement using all of the information provided so far.

FETCH

Fetch the results into the define values.

CLOSE

Free up resources and deallocate memory.

 

当一个Oracle实例接收一条sql后
1、Create a Cursor 创建游标
2、Parse the Statement 分析语句
3、Describe Results of a Query 描述查询的结果集
4、Define Output of a Query 定义查询的输出数据
5、Bind Any Variables 绑定变量
6、Parallelize the Statement 并行执行语句
7、Run the Statement 运行语句
8、Fetch Rows of a Query 取查询出来的行
9、Close the Cursor 关闭游标

解析(PARSE):
1.在共享池中查找SQL语句
2.检查语法
3.检查语义和相关的权限
4.合并(MERGE)视图定义和子查询
5.确定执行计划

绑定(BIND):
1.在语句中查找绑定变量
2.赋值(或重新赋值)

执行(EXECUTE):
1.应用执行计划
2.执行必要的I/O和排序操作

 

提取(FETCH):
1.从查询结果中返回记录
2.必要时进行排序
3.使用ARRAY FETCH机制

--------------------------------------------------------------------------------------------------------------

DML 语句的处理
每种类型的语句都需要如下阶段:
第1步: Create a Cursor 创建游标
第2步: Parse the Statement 分析语句
第5步: Bind Any Variables 绑定变量
第7步: Run the Statement 运行语句
第9步: Close the Cursor 关闭游标

如果使用了并行功能,还会包含下面这个阶段:
第6步: Parallelize the Statement 并行执行语句

第1步: 创建游标(Create a Cursor)
由程序接口调用创建一个游标(cursor)。任何SQL语句都会创建它,特别在运行DML语句时,都是自动创建游标的,不需要开发人员干预。多数应用中,游标的创建是自动的。然而,在预编译程序(pro*c)中游标的创建,可能是隐含的,也可能显式的创建。在存储过程中也是这样的。

第2步:分析语句(Parse the Statement)
在语法分析期间,SQL语句从用户进程传送到Oracle,SQL语句经语法分析后,SQL语句本身与分析的信息都被装入到共享SQL区。在该阶段中,可以解决许多类型的错误。

语法分析分别执行下列操作:
翻译SQL语句,验证它是合法的语句,即书写正确
实现数据字典的查找,以验证是否符合表和列的定义
在所要求的对象上获取语法分析锁,使得在语句的语法分析过程中不改变这些对象的定义
验证为存取所涉及的模式对象所需的权限是否满足
决定此语句最佳的执行计划
将它装入共享SQL区
对分布的语句来说,把语句的全部或部分路由到包含所涉及数据的远程节点
* 以上任何一步出错误,都将导致语句报错,中止执行。

第3步: 描述查询结果(Describe Results of a Query)
描述阶段只有在查询结果的各个列是未知时才需要;例如,当查询由用户交互地输入需要输出的列名。在这种情况要用描述阶段来决定查询结果的特征(数据类型,长度和名字)。

第4步: 定义查询的输出数据(Define Output of a Query)
在查询的定义阶段,你指定与查询出的列值对应的接收变量的位置、大小和数据类型,这样我们通过接收变量就可以得到查询结果。如果必要的话,Oracle会自动实现数据类型的转换。这是将接收变量的类型与对应的列类型相比较决定的。

第5步: 绑定变量(Bind Any Variables)
Oracle知道了SQL语句的意思,但仍没有足够的信息用于执行该语句。Oracle 需要得到在语句中列出的所有变量的值。在该例中,Oracle需要得到对department_id列进行限定的值。得到这个值的过程就叫绑定变量(binding variables)
此过程称之为将变量值捆绑进来。程序必须指出可以找到该数值的变量名(该变量被称为捆绑变量,变量名实质上是一个内存地址,相当于指针)。应用的最终用户可能并没有发觉他们正在指定捆绑变量,因为Oracle 的程序可能只是简单地指示他们输入新的值,其实这一切都在程序中自动做了。
因为你指定了变量名,在你再次执行之前无须重新捆绑变量。你可以改变绑定变量的值,而Oracle在每次执行时,仅仅使用内存地址来查找此值。
如果Oracle 需要实现自动数据类型转换的话(除非它们是隐含的或缺省的),你还必须对每个值指定数据类型和长度。关于这些信息可以参考oracle的相关文档,如Oracle Call Interface Programmer's Guide

第6步: 并行执行语句(Parallelize the Statement )
ORACLE 可以在SELECTs, INSERTs, UPDATEs, MERGEs, DELETEs语句中执行相应并行查询操作,对某些DDL操作,如创建索引、用子查询创建表、在分区表上的操作,可以执行并行操作。并行化可导致多个服务器进程(oracle server processes)为同一个SQL语句工作,使该SQL语句可以快速完成,但是会耗费更多的资源,所以除非很有必要,否则不要使用并行查询。

第7步: 执行语句(Run the Statement)
此时,Oracle拥有所有需要的信息与资源,可以真正运行SQL语句了。如果该语句为SELECT查询或INSERT语句,则不需要锁定任何行,因没有数据需要被改变。如果语句为UPDATE或DELETE语句,则该语句影响的所有行都被锁定,防止该用户提交或回滚之前,别的用户对这些数据进行修改。这保证了数据的一致性。
对于某些语句,你可以指定执行的次数,这称为批处理(array processing)。指定执行N次,则绑定变量与定义变量被定义为大小为N的数组的开始位置,这种方法可以减少网络开销,也是优化的技巧之一。

第8步: 取出查询的行(Fetch Rows of a Query)
在fetch阶段,行数据被取出来,每个后续的存取操作检索结果集中的下一行数据,直到最后一行被取出来。上面提到过,批量的fetch是优化的技巧之一。

第9步: 关闭游标(Close the Cursor)
SQL语句处理的最后一个阶段就是关闭游标。

 

 

 

原创粉丝点击