首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 计算机考试 > 等级考试 > 复习指导 >

Oracle的硬解析和软解析(2)

2009-02-17 
说到软解析(soft prase)和硬解析(hard prase),就不能不说一下Oracle对sql的处理过程。当你发出一条sql语句交付Oracle,在执行和获取结果前,Oracle对此sql将进行几个步骤的处理过程:

  解析中的下一个步骤就是检查我们现在正在解析的语句是否已经被其他的session执行过,在这一步我们可能很幸运,我们可以跳过下面的两个步骤: 语句的优化(生成执行计划) 和 生成执行编码。 如果我们能够跳过这两个步骤,我们就实现了一般意义上的软解析, 我们必须解析,优化,并为这条语句生成执行计划。这个特性(distinction)非常重要,当我们开发应用程序的时候,我们会希望大部分的语句都是软解析的,以跳过优化和生成编码的步骤,因为他们和争用(串行化,)(contention)一样,都是非常消耗CPU的操作。如果我们必须硬解析我们语句的大部分的话,在某些情况下我们的系统就会运行的很慢,并不是任何时候(在olap,dss系统应该是个例外吧)
   The way this sharing of SQL in Oracle is accomplished is via the shared pool, a piece of memory in the SGA maintained by Oracle. We covered this topic in chapter 5 but will revisit it again in the context of processing a query. After Oracle parses the query and it passes the syntax and semantic checks ? it will look in the shared pool component of the SGA to see if that same exact query has already been processed by another session. Since it has performed the semantic check it has already figured out:
  在Oracle中共享SQL的方式是通过共享池——SGA中的一块内存(由Oracle系统来维护)——实现的。我们在第五章中讨论了这个主题,并且会在查询处理的章节再次讨论这个主题。当Oracle已经解析了这条语句,并且已经通过语法和语义检查的时候,Oracle就会在SGA的shared pool(共享池)组件中查询,看看,是否已经有一个完全一样的语句已经被另外一个session执行过。因为语句已经通过了oracle的语义检查,并且oracle已经计算出:
  o Exactly what tables are involved具体涉及到哪些表。
  o That we have access to the tables (the proper privileges are there)
  我们拥有访问对应表的个相应权限。等等……
  And so on. Now, it can look at all of the queries in the shared pool that have already been parsed/optimized and generated to see if the work has already been done.现在,可以在所有已经经过解析和优化并且生成的可执行编码的SQL语句搜索,来看看对应的语句是否已经经过解析。
  Soft Parse and session_cashed_cursor parameter January 28, 2002 Reviewer: A reader软解析与session_cashed_cursor参数
  can you explain what means the default value (0) of session_ casched_cursor parameter? Oracle always has a cache of sqls in sga and size of this cache is determinated through init.ora parameter shared_pool_size.
  tom : 你能不能给我解释一下,session_cashed_cursor(默认值为0)参数的含义,Oracle在SGA中始终保持一个sql语句的缓存。这个缓存的大小是由初始化参数shared_pool_size的大小决定的。
  Followup:The default value of ZERO means that by default, ZERO cursors will be cached for your session.
  默认值为0表示,在默认情况下,Oracle不会给你的session缓存游标。
  They will be cached in the shared pool —— but your session will have to find them there. Session Cached Cursors can remove the need to have to "find" them. Consider this example that shows the difference spent when soft parsing without session cached cursors vs soft parsing WITH session cached cursors:他们会被缓存在共享池(Shared Pool)中,但是你的session必须在共享池中去查找他们,session cached cursors可以省略掉去共享池中查找这一步。下面这个例子给你演示了没有缓存游标和缓存了游标之后软解析之间的差别和系统消耗资源的情况

    Code:
  ops$[email]tkyte@ORA817DEV.US.ORACLE.COM[/email]> create table emp as select * from scott.emp;
  Table created.
  ops$[email]tkyte@ORA817DEV.US.ORACLE.COM[/email]> create table run_stats ( runid varchar2(15),
  name varchar2(80), value int );
  Table created.
  ops$[email]tkyte@ORA817DEV.US.ORACLE.COM[/email]> create or replace view stats
  2 as select ’STAT...’ || a.name name, b.value
  3 from v$statname a, v$mystat b
  4 where a.statistic# = b.statistic#
  5 union all
  6 select ’LATCH.’ || name, gets
  7 from v$latch;
  View created.  
  ops$[email]tkyte@ORA817DEV.US.ORACLE.COM[/email]> column name format a40
  ops$[email]tkyte@ORA817DEV.US.ORACLE.COM[/email]> declare
  2 l_start number;
  3 l_cnt number;
  4 begin
  5 execute immediate ’alter session set session_cached_cursors=0’;
  6 insert into run_stats select ’before’, stats.* from stats;
  7
  8 l_start := dbms_utility.get_time;
  9 for i in 1 .. 1000
  10 loop
  11 execute immediate ’select count(*) from emp’ into l_cnt;
  12 end loop;
  13 dbms_output.put_line( (dbms_utility.get_time-l_start) || ’ hsecs’ );
  14
  15 execute immediate ’alter session set session_cached_cursors=100’;
  16 insert into run_stats select ’after 1’, stats.* from stats;
  17
  18 l_start := dbms_utility.get_time;
  19 for i in 1 .. 1000
  20 loop
  21 execute immediate ’select count(*) from emp’ into l_cnt;
  22 end loop;
  23 dbms_output.put_line( (dbms_utility.get_time-l_start) || ’ hsecs’ );
  24
  25 insert into run_stats select ’after 2’, stats.* from stats;
  26 end;
  27 /
  45 hsecs
  35 hsecs
  PL/SQL procedure successfully completed.
  so, session cached cursors RAN faster (i ran this a couple of times, there were no hard parses going on. But the real good news is:因此,在session中缓存游标可以运行的更快(我运行了好几次,没有硬解析的发生),真正可喜的消息是:
  Code:
  ops$[email]tkyte@ORA817DEV.US.ORACLE.COM[/email]> select a.name, b.value-a.value run1,
  c.value-b.value run2,
  2 ( (c.value-b.value)-(b.value-a.value)) diff
  3 from run_stats a, run_stats b, run_stats c
  4 where a.name = b.name
  5 and b.name = c.name
  6 and a.runid = ’before’
  7 and b.runid = ’after 1’
  8 and c.runid = ’after 2’
  9 and (c.value-a.value) > 0
  10 and (c.value-b.value) <> (b.value-a.value)
  11 order by abs( (c.value-b.value)-(b.value-a.value))
  12 /
  NAME RUN1 RUN2 DIFF
  LATCH.checkpoint queue latch 3 4 1
  LATCH.redo allocation 30 31 1
  STAT...consistent gets 5088 5089 1
  STAT...deferred (CURRENT) block cleanout 2 3 1
  applications
  STAT...calls to get snapshot scn: kcmgss 5019 5018 -1
  STAT...enqueue releases 10 9 -1
  STAT...execute count 1015 1014 -1
  STAT...opened cursors cumulative 1015 1014 -1
  STAT...parse count (total) 1015 1014 -1
  STAT...session cursor cache count 0 1 1
  STAT...redo entries 28 27&nb

 

3COME考试频道为您精心整理,希望对您有所帮助,更多信息在http://www.reader8.net/exam/

热点排行