Oracle11g新特性之动态变量窥视

1. 11g之前的绑定变量窥视

我们都知道,为了能够让SQL语句共享执行计划,oracle始终都是强调在进行应用系统的设计时,必须使用绑定变量,也就是用一个变量来代替原来出现在SQL语句里的字面值。比如,对于下面三条SQL语句来说:

select col1 from t where col2 = 1;

select col1 from t where col2 = 2;

select col1 from t where col2 = 3;

我们可以看到,这三条SQL语句几乎一样,只有最后where条件里的字面值(分别是1、2、3)不同而已。但是如果写成这个样子,则oracle是不知道这三条SQL语句是一样的,仍然把它们当作三条完全不同的SQL语句,从而在shared pool里进行硬解析,并生成最终的执行计划。但是我们会发现,这三个执行计划可能都是一样的,因此后面两次生成执行计划的工作可能是完全不必要的,这在典型的OLTP环境中更是如此。由于解析本身属于CPU密集型操作,因此为了降低对CPU的消耗,oracle建议将这样的SQL写成:

select col1 from t where col2 = :v1;

然后,分别将1、2、3传递给v1,这样的话,只需要第一次传入1时进行解析即可。而后面执行2、3时,由于SQL文本本身没有变化,因此直接把执行计划拿来使用即可,不需要再次生成执行计划。

但是,生成执行计划本身是基于概率的理论,在不访问具体表里的数据的前提下,根据你的where条件,来猜测返回的记录数大概是多少,从而判断应该采用怎样的访问路径。很明显,这是一定要参照具体的where条件里的值才能进行猜测的。这样就与节省CPU的初衷产生了矛盾,因为节省CPU的关键是使用绑定变量,你一旦使用了绑定变量,则oracle岂不是不知道你具体的字面值了吗?

为了解决这一问题,oracle引入了绑定变量窥视。所谓绑定变量窥视,就是指oracle在第一次解析SQL语句的时候(也就是说该SQL第一次传入shared pool),会将你输入的绑定变量的值带入SQL语句里,从而参考你的字面值来猜测该SQL大概会返回多少条记录,从而得到优化的执行计划。然后,以后再次执行相同的SQL语句时,不再考虑你所输入的绑定变量的值,直接取出第一次生成的绑定变量。

但是,很可惜的是,使用绑定变量从而共享游标与SQL优化是两个矛盾的目标。Oracle使用绑定变量的前提,是oracle认为大部分的列的数据都是分布比较均匀的。从而,使用第一次的绑定变量的值所得到的执行计划,大多数情况下都能适用于该绑定变量的其他的值。很明显,如果第一次传入的绑定变量的值恰好占整个数据量的百分比较高,从而导致全表扫描的执行计划。而后来传入的绑定变量的值都占整个数据量的百分比都很低,则应该走索引扫描会更好的,但是由于使用了绑定变量,从而oracle并不会再去看你的绑定变量的值,而是直接拿全表扫描的执行计划来用。这时,由于使用了绑定变量,虽然我们达到了游标共享,从而节省CPU的目的,但是SQL的执行计划却不够优化了。

那么我们如何在绑定变量和SQL优化之间进行取舍呢?在OLTP应用中,由于并发性较高,CPU上的争用会比较严重,同时SQL本身执行时间较短,涉及到的数据量较少,解析所占的时间在整个SQL执行时间中占的比例较高,而花在I/O上的时间占的比例较低。因此尽管绑定变量会有SQL不够优化的问题,还是建议使用绑定变量。但是在DSS应用和数据仓库应用中,由于并发性较低,CPU上的争用较轻,同时SQL语句的执行时间都很长,而且主要时间花在等待I/O上,而解析占的比重较低,这时优化SQL执行计划的重要性就体现出来了。因此,建议不要使用绑定变量,而直接使用字面值。但是大多数的情况都是混合应用,既有OLTP又有数据仓库,这时就很难完美的解决该问题了。

我们先来看一下11g之前的绑定变量窥视是如何工作的,以10g为例。

我们先创建一个表,使得其含有的数据分布不均匀,并在该表上创建一个索引。

hr@ora10g > create table t1 as select object_id as id,object_name from dba_objects;
hr@ora10g > update t1 set id=1 where rownum<=10000;
hr@ora10g > commit;
hr@ora10g > create index idx_t1 on t1(id); 

这样,该表里id为的1记录有一万条,而id为其他值的记录都只有一条。从而,我们构建出一个分布不均匀的测试用表。然后,我们收集一下统计信息。注意,这里要收集直方图,为的是要让CBO知道id列上的数据分布不均匀。

hr@ora10g> begin
2 dbms_stats.gather_table_stats(
3 user,
4 ‘t1‘,
5 cascade => true,
6 method_opt => ‘for columns id size 254‘
7 );
8 end;
9 /

我们找到表t1里最大的id,然后以该id作为第一个绑定变量传入,可以想象,该绑定变量将导致走索引。注意,我们这里设定的优化器目标为all_rows。

hr@ora11g > select max(id) from t1;
MAX(ID)
----------
13871
hr@ora10g> alter system flush shared_pool;
hr@ora10g> var v_id number;
hr@ora10g> var v_sql_id varchar2(20);
hr@ora10g> exec :v_id := 13871;
hr@ora10g> select * from t1 where id=:v_id;
此处省略查询结果
hr@ora10g > begin
2 select sql_id into :v_sql_id from v$sql
3 where sql_text like ‘select * from t1 where id=:v_id%‘;
4 end;
5 /
hr@ora10g > select * from table(dbms_xplan.display_cursor(:v_sql_id));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
SQL_ID djwq30cpbcz7k, child number 0
-------------------------------------
select * from t1 where id=:v_id
Plan hash value: 50753647
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 11 (100) |
| 1 | TABLE ACCESS BY INDEX ROWID| T1 | 1365 | 28665| 11 (0) | 00:00:01
|* 2 | INDEX RANGE SCAN | IDX_T1 | 1365 | | 3 (0) | 00:00:01
--------------------------------------------------------------------------------
......
hr@ora10g> exec :v_id := 1;
hr@ora10g> select * from t1 where id=:v_id;
此处省略查询结果
hr@ora10g > begin
2 select sql_id into :v_sql_id from v$sql
3 where sql_text like ‘select * from t1 where id=:v_id%‘;
4 end;
5 /
hr@ora10g > select * from table(dbms_xplan.display_cursor(:v_sql_id));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
SQL_ID djwq30cpbcz7k, child number 0
-------------------------------------
select * from t1 where id=:v_id
Plan hash value: 50753647
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 11 (100) |
| 1 | TABLE ACCESS BY INDEX ROWID| T1 | 1365 | 28665| 11 (0) | 00:00:01
|* 2 | INDEX RANGE SCAN | IDX_T1 | 1365 | | 3 (0) | 00:00:01
--------------------------------------------------------------------------------

从上面结果可以看出,在为绑定变量传入第一个值为13871时,由于返回的记录条数较少,导致走索引扫描。当我们第二次传入绑定变量值1时,oracle不再生成新的执行计划,而直接拿索引扫描的执行路径来用。

但是,如果先传入1的绑定变量值,然后再传入13871的绑定变量值时,会怎样?我们继续测试。

hr@ora10g> alter system flush shared_pool;
hr@ora10g> set autotrace traceonly exp stat;
hr@ora10g> exec :v_id := 1;
hr@ora10g> select * from t1 where id=:v_id;
hr@ora10g > begin
2 select sql_id into :v_sql_id from v$sql
3 where sql_text like ‘select * from t1 where id=:v_id%‘;
4 end;
5 /
hr@ora10g > select * from table(dbms_xplan.display_cursor(:v_sql_id));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
SQL_ID djwq30cpbcz7k, child number 0
-------------------------------------
select * from t1 where id=:v_id
Plan hash value: 3617692013
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 13 (100)| |
|* 1 | TABLE ACCESS FULL | T1 | 8738 | 179K | 13 (0) | 00:00:01 |
--------------------------------------------------------------------------
......
hr@ora10g > exec :v_id := 13871;
hr@ora10g > select * from t1 where id=:v_id;
hr@ora10g > begin
2 select sql_id into :v_sql_id from v$sql
3 where sql_text like ‘select * from t1 where id=:v_id%‘;
4 end;
5 /
hr@ora10g > select * from table(dbms_xplan.display_cursor(:v_sql_id));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
SQL_ID djwq30cpbcz7k, child number 0
-------------------------------------
select * from t1 where id=:v_id
Plan hash value: 3617692013
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 13 (100)| |
|* 1 | TABLE ACCESS FULL | T1 | 8738 | 179K | 13 (0) | 00:00:01 |
--------------------------------------------------------------------------

很明显,先传入1的绑定变量时将导致生成的执行计划走全表扫描。后面传入的13871的绑定变量的最佳执行路径应该是索引扫描,但是由于CBO并不知道这一点,而是直接拿第一次生成的执行计划来用了,于是也走全表扫描了。

2. 11g之后的动态绑定变量窥视

    而从11g开始,这个尴尬的问题开始得到了改善。因此从11g开始,引入了所谓的自适应游标共享(Adaptive Cursor Sharing)。该特性是一个非常复杂的技术,用来平衡游标共享和SQL优化这两个矛盾的目标。11g里不会盲目的共享游标,而是会去查看每个绑定变量,并为不同的绑定变量来产生不同的执行计划。而oracle这么做的前提是,使用多个执行计划的所带来的收益,要比产生多个执行计划所引起的CPU开销要更大。

使用自适应游标共享时,会遵循下面的步骤:

1) 一条新的SQL语句第一次传入shared pool时,还是和以前一样,进行硬解析。而且进行绑定变量窥视,计算where条件各个列的selectivity,同时如果绑定变量所在的列上存在直方图的话,也会去参考该直方图来计算selectivity。该游标会被标记为是一个绑定敏感的游标(bind-sensitive cursor)。同时,oracle还会保留包含绑定变量的where条件的其他信息,比如selectivity等。Oracle会为该谓词的selectivity维持一个范围,oracle叫做立方体(cube)。只要传入的绑定变量所产生的selectivity落在该范围里面,也就是落在该cube里面,就不产生新的执行计划,而直接拿该cube所对应的执行计划来用。

2) 下次再次执行相同的SQL时,传入了新的绑定变量,假设使用新的绑定变量的谓词的selectivity落在已经存在的cube范围里,于是这次SQL的执行会使用该cube所对应的执行计划。

3) 相同的查询再次执行时,假设所使用的新的绑定变量导致这时候的selectivity不再落在已经存在的cube里了,于是也就找不到对应的执行计划。于是系统会进行一个硬解析,这将产生第二个新的执行计划。而且新的selectivity以及对应的cube也会保存下来。也就是说,这时,我们分别有两个cube以及两个执行计划。

4) 相同的查询再次执行时,假设所使用的新的绑定变量导致这时候的selectivity不落在现存的两个cube中的任何一个,所以系统又会进行硬解析。假设这时硬解析所产生的执行计划与第一次产生执行计划一样,也就是说,在第一次评估selectivity的cube时过于保守,导致cube过小,进而导致了这一次的不必要的硬解析。于是,oracle会将第一次产生的cube与这次产生的cube合并成一个新的更大的cube。那么,下次再次进行软解析的时候,如果selectivity落在新的cube里,则会使用第一次所产生的执行计划。

我们从这里可以看到,11g对这个问题的处理非常精彩。这样做的结果是,系统开始运行时,CPU消耗可能会比较严重,但是随着系统不断运行,cube的不断合并从而不断扩大,于是系统的CPU消耗会不断下降,同时执行计划也会更加的合理。

我们来做个试验进行验证。我们采用11g新引入的执行计划管理特性来验证该特性。

与10g中的测试一样,创建一个数据分布不均匀的表,在数据分布不均匀的列上创建索引,并收集统计信息,收集时注意要收集直方图,从而让CBO知道该列上的数据分布不均匀。

hr@ora11g > create table t1 as select object_id as id,object_name from dba_objects;
hr@ora11g > select count(*) from t1;
COUNT(*)
----------
12064
hr@ora11g > update t1 set id=1 where rownum<=10000;
hr@ora11g > commit;
hr@ora11g > create index idx_t1 on t1(id);
hr@ora11g > begin
2 dbms_stats.gather_table_stats(
3 user,
4 ‘t1‘,
5 cascade => true,
6 method_opt => ‘for columns id size 254‘
7 );
8 end;
9 / 

我们找到表t1里最大的id,然后以该id作为第一个绑定变量传入,可以想象,该绑定变量将导致走索引。

hr@ora11g > select max(id) from t1;
MAX(ID)
----------
12462
我们将optimizer_capture_plan_baselines设置为true,从而让oracle自动获取plan baseline。
hr@ora11g > alter system set OPTIMIZER_CAPTURE_PLAN_BASELINES=true;
hr@ora11g > alter system flush shared_pool;
hr@ora11g > var v_id number;
hr@ora11g > exec :v_id := 12462;
hr@ora11g > select * from t1 where id=:v_id;
hr@ora11g > select * from t1 where id=:v_id; 

我们运行两遍select * from t1 where id=:v_id,从而让oracle捕获plan baseline。我们知道id为12462的记录只有一条,因此该SQL应该使用索引扫描。然后我们再为绑定变量传入1,我们知道id为1的记录有一万条,所以较好的执行计划不应该走已经生成的执行计划,而应该走全表扫描。

hr@ora11g > exec :v_id := 1;
hr@ora11g > set autotrace traceonly stat;
--之所以设置stat是为了让该sql实际执行,但不要返回所有记录,
hr@ora11g > select * from t1 where id=:v_id;
hr@ora11g > select sql_handle,plan_name,origin,enabled,accepted
2 from dba_sql_plan_baselines where sql_text like ‘select * from t1%‘;
SQL_HANDLE PLAN_NAME ORIGIN ENA ACC
----------------------- ----------------------------- -------------- --- ---
SYS_SQL_ea05bbed6f2f670c SYS_SQL_PLAN_6f2f670c844cb98a AUTO-CAPTURE YES YES
SYS_SQL_ea05bbed6f2f670c SYS_SQL_PLAN_6f2f670cdbd90e8e AUTO-CAPTURE YES NO 

我们可以发现,现在该SQL语句存在两个执行计划了,其中第一个执行计划,也就是accepted为YES的执行计划为v_id等于12462得到的,而第二个执行计划,也就是accepted为NO的是由v_id等于1得到的。第二个执行计划还没有被加入plan baseline,所以优化器不会使用该执行计划。我们将第二个执行计划的accepted改为YES,从而让oracle考虑使用该计划。

hr@ora11g > var cnt number;
hr@ora11g > begin
2 :cnt := dbms_spm.alter_sql_plan_baseline(
3 sql_handle => ‘SYS_SQL_ea05bbed6f2f670c‘,
4 plan_name => ‘SYS_SQL_PLAN_6f2f670cdbd90e8e‘,
5 attribute_name => ‘ACCEPTED‘, attribute_value => ‘YES‘);
6 end;
7 /

我们来看一下这两个执行计划分别是怎样的。

注意:在这里我们要验证oracle会为不同绑定变量生成不同的执行计划时,不能使用set autotrace traceonly exp stat等其他方式。因为set autotrace得出的执行计划始终都是第一次生成的执行计划。我们通过plan baseline从侧面来验证它。当然,我们也可以通过设置sql_trace=true从而将执行计划转储出来进行验证。

SQL> select * from table(dbms_xplan.display_sql_plan_baseline
2 (‘SYS_SQL_ea05bbed6f2f670c‘,‘SYS_SQL_PLAN_6f2f670c844cb98a‘));
......
--------------------------------------------------------------------------------
Plan hash value: 50753647
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6 | 126 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| T1 | 6 | 126 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IDX_T1 | 6 | | 1 (0)| 00:00:01 |
-----------------------------------------------------------------------------------
......
SQL> select * from table(dbms_xplan.display_sql_plan_baseline
2 (‘SYS_SQL_ea05bbed6f2f670c‘,‘SYS_SQL_PLAN_6f2f670cdbd90e8e‘));
......
--------------------------------------------------------------------------------
Plan hash value: 3617692013
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU) | Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6 | 126 | 16 (0) | 00:00:01 |
|* 1 | TABLE ACCESS FULL | T1 | 6 | 126 | 16 (0) | 00:00:01 |
--------------------------------------------------------------------------
......

很明显,第一个是索引扫描,第二个是全表扫描。同样,我们来看一下v$sql里该sql语句有几条记录。

hr@ora11g > select sql_text,sql_id,child_number,plan_hash_value
2 from v$sql where sql_text like ‘select * from t1 where%‘;
SQL_TEXT SQL_ID CHILD_NUMBER PLAN_HASH_VALUE
--------------------------------- ------------- ------------ ----------------
select * from t1 where id=:v_id 7y7tt6xyhas1g 0 50753647 

可以看到,该SQL语句目前在内存里只存在一个执行计划,其plan hash value就等于我们在前面plan baseline里看到的第一个走索引的执行计划的hash value。我们把该执行计划显示出来进行确认。

hr@ora11g > select * from table(dbms_xplan.display_cursor(‘7y7tt6xyhas1g‘,0));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
SQL_ID 7y7tt6xyhas1g, child number 0
-------------------------------------
select * from t1 where id=:v_id
Plan hash value: 50753647
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | | | 2 (100) | |
| 1 | TABLE ACCESS BY INDEX ROWID| T1 | 1 | 21 | 2 (0) | 00:00:01 |
|* 2 | INDEX RANGE SCAN | IDX_T1 | 1 | | 1 (0) | 00:00:01 |
...... 

结果很明显,正是走索引的执行计划。然后我们继续为帮定变量传入1,多执行几次。

[email protected] > exec :v_id := 1;

[email protected] > set autotrace traceonly stat;

[email protected] > select * from t1 where id=:v_id;

[email protected] > select * from t1 where id=:v_id;

[email protected] > select * from t1 where id=:v_id;

注意:这里,我们之所以要多执行几次,主要是因为如果只是执行一次或两次,oracle能够认识到你传入的绑定变量落在了第一次的绑定变量(12462)所在的cube之外,但是oracle认为你可能只是偶尔执行该绑定变量,所以并不一定会使用另外那个全表扫描的执行计划。多执行几次以后,你会发现consistent gets突然从1390直线下降到了715,这时就说明oracle开始使用新的全表扫描的执行计划了。

然后,这时我们再去查看v$sql里该sql语句有几条记录。

hr@ora11g > select sql_text,sql_id,child_number,plan_hash_value
2 from v$sql where sql_text like ‘select * from t1 where%‘;
SQL_TEXT SQL_ID CHILD_NUMBER PLAN_HASH_VALUE
--------------------------------- ------------- ------------ ----------------
select * from t1 where id=:v_id 7y7tt6xyhas1g 0 50753647
select * from t1 where id=:v_id 7y7tt6xyhas1g 1 3617692013 

我们发现,该SQL语句在内存里存在两条记录了,也就是存在两个子游标了,分别对应了不同的执行计划。同样,我们来看一下新产生的子游标,也就是child_number为1的执行计划是怎样的。

SQL> select * from table(dbms_xplan.display_cursor(‘7y7tt6xyhas1g‘,1));

PLAN_TABLE_OUTPUT

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

SQL_ID 7y7tt6xyhas1g, child number 1

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

select * from t1 where id=:v_id

Plan hash value: 3617692013

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

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

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

| 0 | SELECT STATEMENT | | | | 16 (100) | |

|* 1 | TABLE ACCESS FULL| T1 | 9974 | 204K | 16 (0) | 00:00:01 |

......

我们还可以从另外的角度来验证11g里的动态绑定变量窥视,也就是设置sql_trace的方式。这个方式比较简单,只要先发出:alter session set sql_trace=true以后,传入两个不同的绑定变量,然后分别就不同的绑定变量多执行几次。最后调用tkprof对跟踪文件进行分析。这里注意两个地方,第一是跟踪文件位于ADR中,不再位于user_dump_dest参数所指定的目录里了。就这里的跟踪文件而言,其所在位置缺省为:$ORACLE_HOME/diag/rdbms/<DB name>/<SID>/trace目录下;第二个要注意的是使用tkprof时,添加aggregate=no选项,缺省会将相同SQL语句合并,这样你就发现不到对于相同SQL语句的不同的执行计划了。

这里节选部分使用tkprof得到的文件内容,如下所示。

......
SQL ID : 7y7tt6xyhas1g
select *
from
t1 where id=:v_id
......
Rows Row Source Operation
------- ---------------------------------------------------
10000 TABLE ACCESS BY INDEX ROWID T1 (cr=1390 pr=0 pw=0 time=446 us cost=2 size=21 card=1)
10000 INDEX RANGE SCAN IDX_T1 (cr=687 pr=0 pw=0 time=228 us cost=1 size=0 card=1)(object id 12463)
......
SQL ID : 7y7tt6xyhas1g
select *
from
t1 where id=:v_id
......
Rows Row Source Operation
------- ---------------------------------------------------
10000 TABLE ACCESS FULL T1 (cr=715 pr=0 pw=0 time=142 us cost=16 size=209454 card=9974)
...... 

从这里也可以很清楚的看到,对于不同的绑定变量,oracle能够自行选择是否应该生成更好的执行计划并使用该执行计划。

来自网络:http://tech.it168.com/db/2007-09-24/200709241709921_1.shtml

Oracle11g新特性之动态变量窥视,布布扣,bubuko.com

时间: 2024-10-27 14:13:24

Oracle11g新特性之动态变量窥视的相关文章

Oracle11g新特性注意事项

在从oracle10g升级到oracle11g后,就需要对oracle11g的新特性进行了解,这些特性可能会对应用及性能产生影响,需要调整. 1. Oracle11g密码过期策略 oracle11g中默认在default概要文件中设置了PASSWORD_LIFE_TIME=180天后过期,到期后会自动改密码, 会影响应用的应用. SQL> alter profile default limit password_life_time unlimited; 2. Oracle11g对用户名密码大小写

Oracle11g 新特性:优化Rman备份UNDO表空间

Oracle11gR1的新特性,Rman备份UNDO表空间时排除已经提交的会话对应的数据,提高了Rman备份的效率. 官方文档:http://docs.oracle.com/cd/B28359_01/server.111/b28279/chapter1.htm#AREANO02323 我们知道,UNDO表空间主要用于存储前镜像数据,这些数据在回滚以及恢复过程中可能被用到.但是一个生产数据库的UNDO表空间可能会变得非常巨大,而备份完整的UNDO数据文件在恢复时一般可能用到的比例很小. 测试一下:

Oracle11g新特性导致空表不能导出问题

    ORACLE 11G在用EXP导出时,发现空表(没有数据或者没有用过的表)不能导出了. 查了一下资料,说是Oracle 11G中有个新特性,当表无数据时,不分配segment,以节省空间,所以这些表也没能导出来.用下面的SQL查询,发现不能导出的表, segment_created 字段值都是 'NO'. Select segment_created,table_name from user_tables where segment_created = 'NO'; 解决的办法: 设置de

atitit.Oracle 9 10 11 12新特性attilax总结

atitit.Oracle 9  10 11  12新特性 1. ORACLE 11G新特性 1 1.1. oracle11G新特性 1 1.2. 审计 1 1.3. 1.   审计简介 1 1.4. 其他(大部分是管理功能) 2 2. Oracle 12c 的 12 个新特性 2 2.1. 2 Improved Defaults 增强了DEFAULT, default目前可以直接指代sequence了,同时增强了default充当identity的能力 2 2.2. Easy Top-N an

ORACLE 11g 由新特性引发lsnrctl hang住卡死迷雾的详细剖析历程

1.问题描述 同事说卡住了,连接oracle数据库很慢,需要很久,连上了做一个简单的查询也非常慢,感觉像是hang主了一般. 2.分析oracle服务器负载 一开始登录进去,查看oracle服务器,负载很低,服务器毫无压力,感觉不是服务器卡的问题了: [[email protected] data]# w 19:59:47 up 122 days,  4:32,  4 users,  load average: 0.65, 0.71, 0.59 USER     TTY      FROM   

oracle 11g 新特性

1.Exadata是结合了数据库威力的硬件. 闪存:不同于数据库闪存,这是一个基于文件扩展的常驻SGA缓冲区的高速缓存(类似于交换区),为数据库提供二级缓存.当数据库被换出SGA时该文件被使用. 存储索引:利用最小值/最大值使查询运行得更快.主要维护数据的摘要信息.内存结构驻留在存储单元层面上.对于一个存储单元而言,存储索引最多可以存储8个查询表列的最小值/最大值.存储索引指示数据如何存储在存储单元上(就像分区的最小值/最大值). 2.高级压缩 允许数据在更新和插入表时保持压缩 create t

Oracle 11g 新特性(一)-- 虚拟列

数据库版本: Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Oracle11g 增加了虚拟列的新特性, 具体说明如下: 1> 只能在堆组织表(普通表)上创建虚拟列,不能在索引组织表.外部表.临时表上创建虚拟列 2> 虚拟列不能是LOB或者RAW类型 3> 虚拟列的值并不是真实存在的,只有用到时,才根据表达式计算出虚拟列的值,磁盘上并不存放 4> 可把虚拟列当做分区关键字建立分区表,这是ORACLE

[转]Oracle 11g 新特性 -- SQL Plan Management 示例

目录 一 SPM 说明 相关名词说明 SPM的特点 与profile和outline相比更加灵活的控制手段 SPM使计划真正的稳定 SPM的控制方式 SPM如何捕捉加载执行计划 自动捕捉 批量导入 执行计划的选择过程 执行计划的演化evolution 修改已有的Baseline 相关MOS 文档 二 SPM 示例 自动捕捉 手工捕获执行计划 演化SQL Plan Baselines 完整示例 修改 Plan Baselines 显示SQL Plan Baselines 设置SQL Managem

web新特性 之 WebSocket

详情参见:你真的了解WebSocket吗?     WebSocket系列教程   HTML5新特性之WebSocket WebSocket协议是基于TCP的一种新的协议.WebSocket最初在HTML5规范中被引用为TCP连接,作为基于TCP的套接字API的占位符.它实现了浏览器与服务器全双工(full-duplex)通信.其本质是保持TCP连接,在浏览器和服务端通过Socket进行通信. 服务端与客户端的连接不断开,实现全双工的操作.及服务端或是客户端都会给对方发送消息. WebSocke