« FOR UPDATE SKIP LOCKED语句中的逻辑读 »
Oracle » http://www.anysql.net/oracle/oracle_skip_locked_gets.html 2007-08-06今天发现这样的一个语句逻辑读很高, 在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.


我想主要就是为了consistent read, 而花在undo block上了.
主要是每一条被别人锁住的行, 都要处理一次.
skip locked 还是很有用的-_-