Chinaunix首页 | 论坛 | 博客
  • 博客访问: 11683848
  • 博文数量: 8065
  • 博客积分: 10002
  • 博客等级: 中将
  • 技术积分: 96708
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-16 17:06
文章分类

全部博文(8065)

文章存档

2008年(8065)

分类: 服务器与存储

2008-07-16 10:45:22

FAST DUAL执行计划是Oracle10g的新特性。对于利用DUAL进行的计算,可以不用真正的访问表,从而快速的得到结果。





这个改变似乎并不起眼,但是累计起来对于系统的影响就是很大的。

下面看一个实际系统中的例子,由于中间件采用了WEBLOGIC,中间件为了确保数据库连接没有问题,需要在每个SQL前面执行一个SELECT 1 FROM DUAL语句,通过这个执行过程来检测数据库连接是否正常。

如果不设置连接检查,那么一旦网络出现故障,可能导致这个连接后面所有的SQL运行出错。

虽然只是一个SELECT 1 FROM DUAL语句,但是由于执行次数众多,在V$SQL中已经可以看到执行次数和BUFFER_GETS:

SQL> SELECT EXECUTIONS, BUFFER_GETS FROM V$SQL WHERE SQL_TEXT = 'SELECT 1 FROM DUAL';

EXECUTIONS BUFFER_GETS
---------- -----------
27674608 83025056

1 row selected.

SQL> SELECT * FROM V$VERSION;

BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.4.0 - 64bit Production PL/SQL Release 9.2.0.4.0 - Production
CORE 9.2.0.3.0 Production
TNS for Solaris: Version 9.2.0.4.0 - Production
NLSRTL Version 9.2.0.4.0 - Production

虽然一次DUAL表的访问一般只有3个逻辑读,但是积少成多。在另一个产品库中,居然发生了溢出:

SQL> SELECT EXECUTIONS, BUFFER_GETS FROM V$SQL WHERE SQL_TEXT = 'SELECT 1 FROM DUAL';

EXECUTIONS BUFFER_GETS
---------- -----------
743695660 -2.064E+09

关于BUFFER_GETS溢出的描述可以参考:http://yangtingkun.itpub.net/post/468/385990

最后来看看10g的产品库:

SQL> SELECT EXECUTIONS, BUFFER_GETS FROM V$SQL WHERE SQL_TEXT = 'SELECT 1 FROM DUAL';

EXECUTIONS BUFFER_GETS
---------- -----------
48321325 110

将近5千万次执行,而BUFFER_GETS才110。这就是10g的新特性FAST DUAL的功劳。

SQL> SET AUTOT ON
SQL> SELECT 1 FROM DUAL;

1
----------
1

已选择 1 行。

执行计划
----------------------------------------------------------
Plan hash value: 1546270724

-----------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-----------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 (0)| 00:00:01 |
| 1 | FAST DUAL | | 1 | 2 (0)| 00:00:01 |
-----------------------------------------------------------------

统计信息
----------------------------------------------------------
0 recursive calls
0 db block gets
0 consistent gets
0 physical reads
0 redo size
509 bytes sent via SQL*Net to client
492 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed

SQL> SELECT * FROM DUAL;

D
-
X

已选择 1 行。

执行计划
----------------------------------------------------------
Plan hash value: 3543395131

--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| DUAL | 1 | 2 | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------

统计信息
----------------------------------------------------------
0 recursive calls
0 db block gets
3 consistent gets
0 physical reads
0 redo size
512 bytes sent via SQL*Net to client
492 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed

如果是用DUAL表进行计算,而不是从中取出记录的话,Oracle采用了FAST DUAL执行计划,而没有真正访问表,因此逻辑读为0;对比SELECT * FROM DUAL,由于Oracle仍然要访问DUAL表才能取出其中的内容,因此仍然需要三个逻辑读。

阅读(255) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~