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.

留言 (3)

我想主要就是为了consistent read, 而花在undo block上了.

主要是每一条被别人锁住的行, 都要处理一次.

skip locked 还是很有用的-_-

发表留言:

« Previous | Main | Next »

英语900句 | English 900

  • I don't want to put you to any trouble.
  • 我不想麻烦你.
  • Excuse me, would you give me a hand?
  • 对不起, 你能帮我个忙吗?
  • I'd be glad to help.
  • 我乐意帮忙.
  • Would you mind mailing this letter for me?
  • 你能替我寄这封信吗?
  • I have so many things to do before I leave.
  • 我走之前还有很多事情要做.