首页 | 摘要显示 | 上一页 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 下一页

Oracle Archives

Oracle 11g性能提升 -- Server Connection Pool

    在应用服务器这一层, 我们已经使用Connection Pool了, 可以有效地降低服务器上的连接的数量, 不过还是有不足之处的. 当你的访问量达到一定的规模时, 你会发现一台或几台应用服务器根本就解决不了问题, 在有些世界级的网站中, 应用服务器的数量可能是上千台的, 当每个应用服务器产生4-5个连接时, 你会发现Oracle服务器端便有了4-5千个物理连接. 象PHP程序, 要求每一个Web Server进程都至少有一个连接. 因此Oracle在11g中引入了Database Resident Connection Pool的功能, 这样客户端就可以不管连接池了, 由Oracle在服务器端进行连接共享控制.

    通过增加一个后台进程CMON(Connection Monitor)来管理连接, 应用发出连接请求时, 实际上是连接到CMON进程, 然后由CMON进程分配一个已经连接好的后台进程, 当客户端连接关闭后, 这个后台进程又交由CMON进程管理. 估计PHP这类的Web程序要有福气了, 不需要去实现连接池的代码了.

    但还有两个问题需要问, 可能会在正式的文档中有详细的说明:

1, 如果我连上去后, 一直不关闭连接, 只是保持空闲状态, 后台进程怎么办?
2, 如果应用中不停地进行连接和断开, CMON能顶得住吗? 每秒钟能接受多少个连接?

    和MTS比到底有多少的优势? 这是值得我们继续关注的技术.

July 13, 2007

Oracle 11g性能提升 -- 其他地方

    看白皮书上这么多的功能, 如果在11g中能很成熟, 那真是一个变化比较大的改进, 来看一下关于性能方面的其他改进吧.

    1, RAC节点通信协议的改进.

    11g中的协议比较智能, 可以根据节点的负荷作出动态的调整, 大大减少节点之间的消息传递量. 说老实话不知道是如何工作的.

    2, 边恢复边Open的Physical Standby -- Highly Available Reader Farms

    这个功能肯定很受大公司的欢迎, 因为以前的Data Guard不能做到这样, 当Open时同主库的延迟会越来越大, 而在11g中则不存在这样的延迟, 因此可以建几个这样的Standby来分担读操作, 估计Shareplex或Realsync这样的软件市场要受到一定的影响了, 我对Log的研究也变得越来越没有价值了.

    3, 面向OLTP的压缩表

    在新的压缩技术中, Oracle可以去掉了压缩表的诸多限制, 使之可以适合OLTP的环境. 这样Oracle可以充分利用闲的CPU的资源(CPU越来越历害了), 以降低IO的消耗(IO的提高还是很慢).

    4, 新的分区类型, 及更多的复合分区方法

    新增了一种Interval分区, 如指定每30天一个分区, 则Oracle会为30天后记录自动增加一个分区, 而不需要DBA提前创建. 还增加了更多的复合分区方法, 下表中纵向为主分区的类型, 横向为子分区的类型.
 RangeListHash
RangeYesYesYes
ListYesYesYes
IntervalYesYesYes

    5, 虚拟列 -- Virtual Column

    11g以前的创建一个函数索引时, 实际上也是加了一个虚拟列的, 只不过DESC也不显示出来. 在11g中则可以在建表时加上虚拟列, 并可将这个列用于SQL, 分区列中, 还可以在上面建索引(这和函数索引有区别吗?).
CREATE TABLE t1 (
c1 NUMBER,
c2 NUMBER,
vc AS (c1 + c2) VIRTUAL)

    让我们一起来验证11g中这些让人兴奋的功能吧.

August 2, 2007

如何以较好的性能访问Oracle内核表?

    Oracle通常在一些内核表的INDX列有特殊的索引, 如果能用到这些索引, 则访问很快, 否则在会话数很多的数据库上很慢. 最简单的访问就是用等于去访问.

SQL> SELECT INDX, KSLESWTS,KSLESTIM FROM X$KSLEI WHERE INDX=1;

      INDX   KSLESWTS   KSLESTIM
---------- ---------- ----------
         1          0          0

Elapsed: 00:00:00.01

    换成IN看看? 有点慢, 因为这时不能使用索引.

SQL> SELECT INDX, KSLESWTS,KSLESTIM FROM X$KSLEI WHERE INDX IN (100,200);

      INDX   KSLESWTS   KSLESTIM
---------- ---------- ----------
       100          0          0
       200          6      57927

Elapsed: 00:00:02.11

    这么慢是不行的!, 加一个Hint试试吧.

SQL> SELECT /*+ USE_CONCAT */ INDX, KSLESWTS,KSLESTIM
   2 FROM X$KSLEI WHERE INDX IN (100,200);

      INDX   KSLESWTS   KSLESTIM
---------- ---------- ----------
       200          6      57927
       100          0          0

Elapsed: 00:00:00.03

    一不小心加个-1, 结果很惨啊!

SQL> SELECT /*+ USE_CONCAT */ INDX, KSLESWTS,KSLESTIM
   2 FROM X$KSLEI WHERE INDX IN (100,200,-1);

      INDX   KSLESWTS   KSLESTIM
---------- ---------- ----------
       200          6      57927
       100          0          0

Elapsed: 00:00:02.12

    后来给eagle_fan看了, 他建议试一下一个大的正数.

SQL> SELECT /*+ USE_CONCAT */ INDX, KSLESWTS,KSLESTIM
   2 FROM X$KSLEI WHERE INDX IN (100,200,100000);

      INDX   KSLESWTS   KSLESTIM
---------- ---------- ----------
       200          6      57927
       100          0          0

Elapsed: 00:00:00.02

    和普通的索引不一样, 一般只能在等于情况下用到, 因为它不是一个真正存在的索引, 而是一种算法.

August 3, 2007

LOG_ARCHIVE_FORMAT中%r值从哪儿来的?

    当数据库从9i或8i升级到10g时, 如果compatible参数也设成了10以上, 则LOG_ARCHIVE_FORMAT参数中必须包含%s, %t, %r参数. 其中%s是Log Seuqence; %t是Thread ID, RAC的节点中设有THREAD参数, 就是这个值了; %r指的是Resetlog ID了, 比较新, 得从Oracle 10g中增加的跨Resetlogs恢复功能说起.

    为了支持这个功能, Oracle 10g在控制文件中新增了一部份内容, 就是历次Open Resetlogs的经过, 每经历一次Open Restlogs就生成了一个新的Incarnation(不知道如何翻译这个单词了), 反应到数据库中则是V$DATABASE_INCARNATION视图(基表x$kccic, 说明是存放在控制文件中的). 我这儿没有经过多次open resetlogs的数据库, 等一下验证一下. 查一个从来没有Open Resetlogs的库吧, 如下所示:

ASQL> SELECT * FROM v$DATABASE_INCARNATION/G;

INCARNATION#                  : 1
RESETLOGS_CHANGE#             : 1
RESETLOGS_TIME                : 2007-07-16 17:28:06.0
PRIOR_RESETLOGS_CHANGE#       : 0
PRIOR_RESETLOGS_TIME          : null
STATUS                        : CURRENT
RESETLOGS_ID                  : 628104486
PRIOR_INCARNATION#            : 0
FLASHBACK_DATABASE_ALLOWED    : NO

1 rows returned.

    从这儿可以推导出一个观点, 当你重建控制文件后, 将丢失跨Resetlogs恢复的能力. 还好控制文件的参数大部份都可以动态改了, 基本上没有重建它的需要了. 上面的值中, STATUS列的值为CURRENT表示是当前的Incarnation, 另外还可以从V$DATABASE中获得当前正在使用的Incarnation. 如下所示:

ASQL> SELECT LAST_OPEN_INCARNATION# FROM V$DATABASE;

LAST_OPEN_INCARNATION#
----------------------
                     1

1 rows returned.

    有些部份还只是猜测, 如有错误, 请理解.

August 6, 2007

FOR UPDATE SKIP LOCKED语句中的逻辑读

    今天发现这样的一个语句逻辑读很高, 在Physical Standby上打开查询, 发现逻辑读是很低的, 只有源库的百分之一, 百思不得其解. 回来后建了如下表做测试:

SQL> CREATE TABLE T_SKIPLOCKED
  2  (
  3     NO NUMBER(2),
  4     COL2 CHAR(200),
  5     CONSTRAINT PK_T_SKIPLOCKED PRIMARY KEY (NO)
  6  );

Table created.

SQL> INSERT INTO T_SKIPLOCKED SELECT ROWNUM, OBJECT_NAME
   2 FROM ALL_OBJECTS WHERE ROWNUM < 11;

10 rows created.

    先进行最简单的SELECT语句(SELECT * FROM T_SKIPLOCKED WHERE NO=2), 可以发现有两个逻辑读, 一个是Index的Root, 另一个是表上的数据块, 容易理解.

Statistics
----------------------------------------------------------
          0  db block gets
          2  consistent gets

    接下来测试一下后面加上"FOR UPDATE SKIP LOCKED"的情况, 这时没有别的会话锁定记录. 同样地只有两上逻辑读, 一个是Index的Root, 另一个是表上的X模式的读.

Statistics
----------------------------------------------------------
          1  db block gets
          2  consistent gets

    先不要关闭上面这个连接, 也不要发Commit或Rollback命令, 我们新开一个窗口, 再来发一下同样的一句语句, 看看有多少个逻辑读. 虽然这个SQL语句不返回任何记录, 但是逻辑读还是很高的.

Statistics
----------------------------------------------------------
          1  db block gets
          5  consistent gets

    根据我的初步理解及仔细监控V$SYSSTAT, 发现每执行一次上面的语句, 都有Cleanout/Consistent Changes及CR Block created发生, 这中间可能经过以下几步:

   1 Index Root
   1 table block (x mode)
   1 undo header
   1 undo block  
   1 consistent get from cr block

    后来我还试验了被别的会话锁住多条记录的情况, 发现逻辑读的数量和被锁住的记录数有比例关系, 只是我现在还没有办法区别那些是db block gets.

上一页 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 下一页

当前分类: Oracle

Creative Commons License
本站版权: 共用创作 CC
署名-非商业性-相同方式分享
本站基于MT-3.36免费版
(©)版权所有, 2004 - 2008, www.AnySQL.net, 保留所有权利.
MSN: loufangxin(a)msn.com, Mail: anysql(at)126.com/support(at)iamdba.com, Skype ID:anysql