Oracle SQL的硬解析、软解析、软软解析
Oracle中每条sql在执行前都要解析,解析分为硬解析、软解析、软软解析。
Oracle会缓存DML语句,相同的DML语句会进行软解析。但不会缓存DDL语句,所以DDL每次都做硬解析。硬解析是一个很耗时的操作,所以应用程序内部很少执行执行DDL。DDL一般在部署前执行。
sql语句执行步骤:
1.语法检查(syntax check)
2.语义检查(symantic check): 对象是否存在,是否有权限。
3.sql解析(parse): 利用内部算法对sql进行解析,生成解析树及执行计划。
4.执行sql,返回结果(execute and return)
首先了解一下sql解析时用到的内存结构——shared pool:
shared pool是一块内存池,里边又被分成了很多小的区块,每个块有他们的作用
1.free (空闲)
2.library cache (库缓存,缓存sql语句以及sql所对应的执行计划)
3.row cache (字典缓存——库里有多少表,多少用户,多少个列,列的名字,列的数据类型,每个表多大等等都属于数据库自身信息。)
一个sql 语句,进入到数据库后,server process 会拿着sql语句到shared pool中的library cache 里边去找,看sql语句以前是否有执行过。也就是在library cache 里面看有没有这条sql语句以及sql语句所对应的执行计划。(此过程是通过对传递进来的SQL语句使用HASH函数运算得出HASH值,与共享池中现有语句的HASH值进行比较看是否一一对应。现有数据库中SQL语句的HASH值我们可以通过访问v$sql、v$sqlarea、v$sqltext等数据字典中的HASH_VALUE列查询得出。)
Parse主要分为三种:
1.Hard Parse (硬解析)
2.Soft Parse (软解析)
3.Soft Soft Parse
Hard Parse:对提交的Sql完全重新从头进行解析(当在shared Pool中找不到时候将会进行此操作),总共有一下5个执行步骤:
1.语法分析
2.权限与对象检查
3.在共享池中检查是否有完全相同的之前完全解析好的. 如果存在,直接跳过4和5,运行Sql, 此时算soft parse.
4.选择执行计划
5.产生执行计划
注:创建解析树、生成执行计划对于sql的执行来说是开销昂贵的动作,所以,应当极力避免硬解析,尽量使用软解析。这就是在很多项目中,倡导开发设计人员对功能相同的代码要努力保持代码的一致性,以及要在程序中多使用绑定变量的原因。
Soft Parse: 在Shared Pool中找到了与之完全相同的Sql解析好的结果后会跳过Hard Parse中的后面的两个步骤。
Soft Soft Parse:当设置了session_cursor_cache这个参数之后,Cursor被直接Cache在当前Session的PGA中的,在解析的时候只需要对其语法分析、权限对象分析之后就可以转到PGA中查找了,如果发现完全相同的Cursor,就可以直接去取结果了,也就就是实现了 Soft Soft Parse.
如果SQL语句的HASH值一致,那么ORACLE事实上还需要对SQL语句的语义进行再次检测,以决定是否一致。那么为什么Oracle需要再次对语句文本进行检测呢?不是SQL语句的HASH值已经对应上了?事实上就算是SQL语句的HASH值已经对应上了,并不能说明这两条SQL语句就已经可以共享了。
例如:假如用户SYS有自己的一张表EMP,他要执行查询语句:select * from emp; 用户SYSTEM也有一张EMP表,同样要查询select * from emp;这样他们两条语句在文本上是一模一样的,他们的HASH值也会一样,但是由于涉及到查询的相关表不一样,他们事实上是无法共享的.
下面我们来看实验:
数据库版本:Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
create table test as select * from user_objects where 1<>1;
begin
dbms_stats.gather_table_stats('TOUGH','TEST');
end;
alter system flush shared_pool;
- 硬解析
select * from test where object_id=20;
select * from test where object_id=30;
- 软解析
select * from test where object_id=40;
select * from test where object_id=40;select * from test where object_id=50;
select * from test where object_id=50;
select * from test where object_id=50;
select * from test where object_id=50;
- 软软解析
begin
for i in 1 .. 4 loop
execute immediate 'select * from test where object_id=:i'
using i;
end loop;
end;
查看解析情况:
select sql_text, s.parse_calls, loads, executions
from v$sql s
where sql_text like 'select * from test where object_id%'
order by 1, 2, 3, 4;
| SQL_TEXT | PARSE_CALLS | LOADS | EXECUTIONS |
| select * from test where object_id=20 | 1 | 1 | 1 |
| select * from test where object_id=30 | 1 | 1 | 1 |
| select * from test where object_id=40 | 2 | 1 | 2 |
| select * from test where object_id=50 | 4 | 1 | 4 |
| select * from test where object_id=:i | 1 | 1 | 4 |
object_id=20 -> 因为没有缓存此条sql,所以硬解析
object_id=30 -> 因为没有缓存此条sql,所以硬解析
object_id=40 -> 因为第一次执行已经缓存此条sql,所以软解析次数为2,硬解析次数为1
object_id=50 -> 因为第一次执行已经缓存此条sql,所以软解析次数为4,硬解析次数为1
object_id=:i -> 用了动态绑定变量,尽管执行了4次,但只做了一次硬解析和一次软解析
字段解释:
PARSE_CALLS - 解析的次数
LOADS - 硬解析的次数
EXECUTIONS - 执行的次数
Oracle SQL的硬解析、软解析、软软解析的更多相关文章
- Oracle SQL的硬解析和软解析
我们都知道在Oracle中每条SQL语句在执行之前都需要经过解析,这里面又分为软解析和硬解析.在Oracle中存在两种类型的SQL语句,一类为 DDL语句(数据定义语言),他们是从来不会共享使用的,也 ...
- [转]ORACLE SQL解析之硬解析和软解析
http://blog.chinaunix.net/uid-25909722-id-3363789.html 当客户端进程,将SQL语句通过监听器发送到Oracle时, 会触发一个Server pro ...
- Oracle硬解析,软解析,软软解析介绍
Oracle数据库中的CURSOR分为两种类型:Shared Cursor 和 Session Cursor 1,Shared Cursor Oracle里的第一种类型的Cursor就是Shared ...
- Oracle SQL Trace 和 10046 事件
http://blog.csdn.net/tianlesoftware/article/details/5857023 一. SQL_TRACE 当SQL语句出现性能问题时,我们可以用SQL_TRAC ...
- Oracle SQL性能优化技巧大总结
http://wenku.baidu.com/link?url=liS0_3fAyX2uXF5MAEQxMOj3YIY4UCcQM4gPfPzHfFcHBXuJTE8rANrwu6GXwdzbmvdV ...
- 共享池之八:软解析、硬解析、软软解析 详解一条SQL在library cache中解析涉及的锁
先来张大图: 结合上图来说明一下解析的各个步骤涉及的锁. 软解析.硬解析.软软解析区别的简单说明: 为了将用户写的sql文本转化为oracle认识的且可执行的语句,这个过程就叫做解析过程. 解析分为硬 ...
- Oracle SQL 硬解析和子游标
Oracle SQL 硬解析和子游标 What reasons will be happening sql hard parse and generating new child cursors 在一 ...
- Oracle sql执行计划解析
Oracle sql执行计划解析 https://blog.csdn.net/xybelieve1990/article/details/50562963 Oracle优化器 Oracle的优化器共有 ...
- 精通 Oracle+Python,第 3 部分:数据解析
进行数据解析的理由不计其数,相关的工具和技巧也同样如此.但是,当您需要用这些数据做一些新的事情时,即使有“合适的”工具可能也是不够的.这一担心对于异类数据源的集成同样存在.用来做这项工作的合适工具迟早 ...
随机推荐
- <Think Complexity> 用字典实现图
今天在图书馆闲逛的时候偶然看见<Think Complexity>(复杂性思考)这本书,下午看了一会儿觉得很有意思.本书第二章讲的是用Python实现的图,特别写篇博客记录. 首先,图 ...
- 安装Laravel之坎坷记述
写这篇文章记录以及分享我安装Laravel框架的一些经验 过程如下: 1.按照官方的描述,第一步是先安装composer来管理依赖=>composer下载传送门 下载之后点击安装,按照提示它需要 ...
- HDU 4433 locker
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4433 这是一道2012年ACM天津赛区现场赛的题目,大意是给出两串数字,求用最少的转换次数将一串(A) ...
- OSI七层模型:TCP/IP && HTTP && WebSocket && MQTT
OSI七层模型分为 物理层: 建立.维护.断开物理连接 处理bit流 数据链路层,将比特组合成字节进而组合成帧,用MAC地址访问介质,错误发现但不能纠正 处理数据帧 Frame 网络层,进行逻辑地址 ...
- 如何通过PhpMyAdmin批量删除MYSQL数据库数据表
使用这个方法前,强烈建议先备份整个数据库.至于怎么备份?你不会么?在本文下方留言吧. 具体方法:复制下面的php执行语句,保存为sql.php文件(注意配置数据库名称.密码.数据表头),通过ftp上传 ...
- ADO.NET笔记(一)XML导入导出和数据库
数据导出成XML文件 #region 数据导出成XML文件 string sql = "select Id, CallerNumber, TelNum, StartDateTime, End ...
- C# IO操作(五)文件的递归加载
本篇是一个案例,其核心通过代码展示代码中的递归这个用法,程序的界面如下:
- win2003域控制器密码遗忘如何修改
在公司遇到这么个事儿,员工搭建QC服务器,设置了域账户登陆系统.但忘记了登录密码,使用PE直接修改sam文件不好用. 1.使用PE进系统修改组登陆方式的账号administrator密码 需符合复 ...
- QT编译mysql驱动
一. 下载mysql C链接库 地址:http://dev.mysql.com/downloads/ 根据当前系统选择下载: 二. 安装下载好的mysql驱动文件 注意,一定要安装在不含有中文.空格以 ...
- linux 定时任务 crontab
为当前用户创建cron服务 1. 键入 crontab -e 编辑crontab服务文件 例如 文件内容如下: */2 * * * * /bin/sh /home/admin/jiaoben/bu ...