SQL语句的解析有软解析soft parse与硬解析hard parse之说.docx
- 文档编号:26837218
- 上传时间:2023-06-23
- 格式:DOCX
- 页数:9
- 大小:16.95KB
SQL语句的解析有软解析soft parse与硬解析hard parse之说.docx
《SQL语句的解析有软解析soft parse与硬解析hard parse之说.docx》由会员分享,可在线阅读,更多相关《SQL语句的解析有软解析soft parse与硬解析hard parse之说.docx(9页珍藏版)》请在冰豆网上搜索。
SQL语句的解析有软解析softparse与硬解析hardparse之说
SQL语句的解析有软解析softparse与硬解析hardparse之说
SQL语句的解析有软解析softparse与硬解析hardparse之说:
以下是5个步骤:
1:
语法是否合法(sql写法)
2:
语义是否合法(权限,对象是否存在)
3:
检查该sql是否在公享池中存在
--如果存在,直接跳过4和5,运行sql.此时算softparse
4:
选择执行计划
5:
产生执行计划
--如果5个步骤全做,这就叫hardparse.
提到软解析(softparse)和硬解析(hardparse),就不能不说一下Oracle对sql的处理过程。
当你发出一条sql语句交付Oracle,在执行和获取结果前,Oracle对此sql将进行几个步骤的处理过程:
1、语法检查(syntaxcheck)
检查此sql的拼写是否语法。
2、语义检查(semanticcheck)
诸如检查sql语句中的访问对象是否存在及该用户是否具备相应的权限。
3、对sql语句进行解析(parse)
利用内部算法对sql进行解析,生成解析树(parsetree)及执行计划(executionplan)。
4、执行sql,返回结果(executeandreturn)
其中,软、硬解析就发生在第三个过程里。
Oracle利用内部的hash算法来取得该sql的hash值,然后在librarycache里查找是否存在该hash值;
假设存在,则将此sql与cache中的进行比较;
假设“相同”,就将利用已有的解析树与执行计划,而省略了优化器的相关工作。
这也就是软解析的过程。
诚然,如果上面的2个假设中任有一个不成立,那么优化器都将进行创建解析树、生成执行计划的动作。
这个过程就叫硬解析。
创建解析树、生成执行计划对于sql的执行来说是开销昂贵的动作,所以,应当极力避免硬解析,尽量使用软解析。
这就是在很多项目中,倡导开发设计人员对功能相同的代码要努力保持代码的一致性,以及要在程序中多使用绑定变量的原因。
软解析、硬解析的一个小测试:
软解析、硬解析的一个小测试:
SQL>createglobaltemporarytablesess_eventoncommitpreserverowsasselect*fromv$session_eventwhere1=0;
TablecreatedSQL>insertintosess_event
2select*fromv$session_event
3wheresid=(selectsidfromv$mystatwhererownum=1);9rowsinsertedSQL>
SQL>SELECTNAME,VALUEFROMV$MYSTATA,V$STATNAMEBWHEREA.STATISTIC#=B.STATISTIC#
2ANDNAMELIKE'parsecount%'
3;NAMEVALUE
--------------------------------------------------------------------------
parsecount(total)32127
parsecount(hard)30365
parsecount(failures)1
SQL>
SQL>begin
2foriin1..10000loop
3executeimmediate'insertintotestvalues('||i||','||i||')';
4endloop;
5commit;
6end;
7/
PL/SQLproceduresuccessfullycompleted
SQL>
SQL>SELECTNAME,VALUEFROMV$MYSTATA,V$STATNAMEBWHEREA.STATISTIC#=B.STATISTIC#
2ANDNAMELIKE'parsecount%';NAMEVALUE
--------------------------------------------------------------------------
parsecount(total)42201
parsecount(hard)40379
parsecount(failures)1没有使用绑定变量(这种写法往往有人误认为使用了绑定,这里就不多解释了)总解析次数:
10074
硬解析次数:
10014
上边2个值除了我们的循环10000次外,还包括其他一些系统表的读写,所以解析次数大于10000,但是我们要注意下面的结果,对于每个SQL
都有一个版本,也就是ORACLE对于每个不同的SQL分别执行了硬解析,下面是共享池最后缓存的数据(部分已经被覆盖)SQL>selectSQL_TEXT,VERSION_COUNT,PARSE_CALLS,EXECUTIONSfromv$sqlareawhereupper(sql_text)like'%TEST%';SQL_TEXTVERSION_COUNTPARSE_CALLSEXECUTIONS
------------------------------------------------------------------------------------------------------------------
insertintotestvalues(9630,9630)111
insertintotestvalues(9950,9950)111
insertintotestvalues(9625,9625)111
insertintotestvalues(9592,9592)111
insertintotestvalues(9940,9940)111
insertintotestvalues(9897,9897)111
中间内容略SQL_TEXTVERSION_COUNTPARSE_CALLSEXECUTIONS
------------------------------------------------------------------------------------------------------------------
insertintotestvalues(9838,9838)111
insertintotestvalues(9716,9716)111
insertintotestvalues(9691,9691)111
insertintotestvalues(9831,9831)111
insertintotestvalues(9992,9992)111
insertintotestvalues(9883,9883)111
insertintotestvalues(9865,9865)111
435rowsselectedSQL>truncatetalbesess_event;truncatetalbesess_eventORA-03290:
无效的截断命令-缺失CLUSTER或TABLE关键字SQL>truncatetablesess_event;TabletruncatedSQL>altersystemflushshared_pool;SystemalteredSQL>
SQL>insertintosess_event
2select*fromv$session_event
3wheresid=(selectsidfromv$mystatwhererownum=1);10rowsinsertedSQL>
SQL>SELECTNAME,VALUEFROMV$MYSTATA,V$STATNAMEBWHEREA.STATISTIC#=B.STATISTIC#
2ANDNAMELIKE'parsecount%';NAMEVALUE
--------------------------------------------------------------------------
parsecount(total)42643
parsecount(hard)40456
parsecount(failures)2SQL>
SQL>begin
2foriin1..10000loop
3executeimmediate'insertintotestvalues(:
v1,:
v2)'usingi,i;
4endloop;
5commit;
6end;
7/PL/SQLproceduresuccessfullycompletedSQL>
SQL>SELECTNAME,VALUEFROMV$MYSTATA,V$STATNAMEBWHEREA.STATISTIC#=B.STATISTIC#
2ANDNAMELIKE'parsecount%';NAMEVALUE
--------------------------------------------------------------------------
parsecount(total)42688
parsecount(hard)40466
parsecount(failures)2下面看下使用绑定变量的情况(真正使用了绑定)总解析次数:
45
硬解析次数:
10
我们可以看出差异是多么大了,呵呵,对于SQL本身只有一次软解析,执行次数为10000
SQL>selectSQL_TEXT,VERSION_COUNT,PARSE_CALLS,EXECUTIONSfromv$sqlareawhereupper(sql_text)like'%TEST%';
SQL_TEXTVERSION_COUNTPARSE_CALLSEXECUTIONS
------------------------------------------------------------------------------------------------------------------
beginforiin1..10000loopexecuteimmediate'insertintotestvalues(:
v1,:
v2111
updatesys.job$setfailures=0,this_date=null,flag=:
1,last_date=:
2,next_dat111
insertintotestvalues(:
v1,:
v2)1110000
selectSQL_TEXT,VERSION_COUNT,PARSE_CALLS,EXECUTIONSfromv$sqlareawhereupper(111
selectSQL_TEXT,VERSION_COUNT,PARSE_CALLS,EXECUTIONSfromv$sqlareawhereupper(111
SQL>altersystemflushshared_pool;
Systemaltered但是我们要注意一个情况,即时同样的SQL如果没有使用绑定变量,ORACLE也会对其执行一次软解析的,但是没有硬解析,如下:
每执行一次SQL,也会同时产生其他写系统表等很多相关的软解析包括查询SQL本身。
硬解析不变。
SQL>insertintotestvalues('1','1111111111');1rowinsertedSQL>commit;CommitcompleteSQL>selectSQL_TEXT,VERSION_COUNT,PARSE_CALLS,EXECUTIONSfromv$sqlareawhereupper(sql_text)like'%TEST%';SQL_TEXTVERSION_COUNTPARSE_CALLSEXECUTIONS
------------------------------------------------------------------------------------------------------------------
updatesys.job$setfailures=0,this_date=null,flag=:
1,last_date=:
2,next_dat111
insertintotestvalues('1','1111111111')111
selectSQL_TEXT,VERSION_COUNT,PARSE_CALLS,EXECUTIONSfromv$sqlareawhereupper(111
selectSQL_TEXT,VERSION_COUNT,PARSE_CALLS,EXECUTIONSfromv$sqlareawhereupper(111SQL>insertintotestvalues('1','1111111111');1rowinsertedSQL>commit;CommitcompleteSQL>selectSQL_TEXT,VERSION_COUNT,PARSE_CALLS,EXECUTIONSfromv$sqlareawhereupper(sql_text)like'%TEST%';SQL_TEXTVERSION_COUNTPARSE_CALLSEXECUTIONS
------------------------------------------------------------------------------------------------------------------
updatesys.job$setfailures=0,this_date=null,flag=:
1,last_date=:
2,next_dat111
insertintotestvalues('1','1111111111')122
selectSQL_TEXT,VERSION_COUNT,PARSE_CALLS,EXECUTIONSfromv$sqlareawhereupper(111
selectSQL_TEXT,VERSION_COUNT,PARSE_CALLS,EXECUTIONSfromv$sqlareawhereupper(122SQL>SQL>SELECTNAME,VALUEFROMV$MYSTATA,V$STATNAMEBWHEREA.STATISTIC#=B.STATISTIC#
2ANDNAMELIKE'parsecount%';NAMEVALUE
--------------------------------------------------------------------------
parsecount(total)42906
parsecount(hard)40520
parsecount(failures)2SQL>insertintotestvalues('1','1111111111');1rowinsertedSQL>commit;CommitcompleteSQL>selectSQL_TEXT,VERSION_COUNT,PARSE_CALLS,EXECUTIONSfromv$sqlareawhereupper(sql_text)like'%TEST%';SQL_TEXTVERSION_COUNTPARSE_CALLSEXECUTIONS
------------------------------------------------------------------------------------------------------------------
begindbsnmp.mgmt_response.get_latest_curs(:
a);end;111
/**//*OracleOEM*/BEGINIF(:
1='READWRITE')THEN------Foraread-111
/**//*OracleOEM*/DECLAREinstance_numberNUMBER;latest_task_idNUMBER;111
updatesys.job$setfailures=0,this_date=null,flag=:
1,last_date=:
2,next_dat144
insertintotestvalues('1','1111111111')133
DELETEFROMMGMT_DB_LATEST_HDM_FINDINGSWHERETARGET_GUID=:
B2ANDCOLLECTION_T233
selectSQL_TEXT,VERSION_COUNT,PARSE_CALLS,EXECUTIONSfromv$sqlareawhereupper(111
selectSQL_TEXT,VERSION_COUNT,PARSE_CALLS,EXECUTIONSfromv$sqlareawhereupper(1338rowsselectedSQL>
SQL>SELECTNAME,VALUEFROMV$MYSTATA,V$STATNAMEBWHEREA.STATISTIC#=B.STATISTIC#
2ANDNAMELIKE'parsecount%';NAMEVALUE
--------------------------------------------------------------------------
parsecount(total)42922
parsecount(hard)40520
parsecount(failures)2SQL>insertintotestvalues('1','1111111111');1rowinsertedSQL>commit;CommitcompleteSQL>insertintotestvalues('1','1111111111');1rowinsertedSQL>commit;CommitcompleteSQL>selectSQL_TEXT,VERSION_COUNT,PARSE_CALLS,EXECUTIONSfromv$sqlareawhereupper(sql_text)like'%TEST%';SQL_TEXTVERSION_COUNTPARSE_CALLSEXECUTIONS
------------------------------------------------------------------------------------------------------------------
begindbsnmp.mgmt_response.get_latest_curs(:
a);end;111
/**//*OracleOEM*/BEGINIF(:
1='READWRITE')THEN------Foraread-111
/**//*OracleOEM*/DECLAREinstance_numberNUMBER;latest_task_idNUMBER;111
updatesys.job$setfailures=0,this_date=null,flag=:
1,last_date=:
2,next_dat155
insertintotestvalues('1','1111111111')155
DELETEFROMMGMT_DB_LATEST_HDM_FINDINGSWHERETARGET_GUID=:
B2ANDCOLLECTION_T233
selectSQL_TEXT,VERSION_COUNT,PARSE_CALLS,EXECUTIONSfromv$sqlareawhereupper(111
selectSQL_TEXT,VERSION_COUNT,PARSE_CALLS,EXECUTIONSfromv$sqlareawhereupper(1448rowsselectedSQL>
SQL>SELECTNAME,VALUEFROMV$MYSTATA,V$STATNAMEBWHEREA.STATISTIC#=B.STATISTIC#
2ANDNAMELIKE'parsecount%';NAMEVALUE
--------------------------------------------------------------------------
parsecount(total)42946
parsecount(hard)40520
parsecount(failures)2SQL>通过这个例子我们也就知道V$SQLAREA中的解析包含什么内容了。
2007-10-2216:
10:
32查看评语»»»
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- SQL语句的解析有软解析soft parse与硬解析hard parse之说 SQL 语句 解析 soft parse hard