有趣的rownum测试(r10笔记第49天)

时间:2022-05-04
本文章向大家介绍有趣的rownum测试(r10笔记第49天),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

rownum在平时的使用中总是一个很自然的语法。如果说这个rownum是否有规律,可能很多人都会模棱两可。到底是还是不是呢,我们来做几个测试来说明。 这个结果也是在一个测试过程中无意发现的,没想到还蛮有意思。 我们会开启两个会话,会话1,会话2 首先初始化数据: create table test_lock as select * from all_objects where rownum<100; 会话1: 运行下面的语句,根据rownum得到5行数据,到底是按照rowid还是按照数值的大小呢。 SQL> select object_id ,rowid from test_lock where rownum<6; OBJECT_ID ROWID ---------- ------------------ 20 AAAVmRAAEAAAAV7AAA 46 AAAVmRAAEAAAAV7AAB 28 AAAVmRAAEAAAAV7AAC 15 AAAVmRAAEAAAAV7AAD 29 AAAVmRAAEAAAAV7AAE 可以从这个输出来看,应该是按照rowid的方式来的。 当然还没有到下结论的时候,我们添加主键或者唯一性索引来看看是否会有变化 添加主键: SQL> alter table test_lock modify(object_id primary key); Table altered. 再次查看rownum的情况,就发生了变化。 SQL> select object_id ,rowid from test_lock where rownum<6; OBJECT_ID ROWID ---------- ------------------ 2 AAAVmRAAEAAAAV7AAw 3 AAAVmRAAEAAAAV7AAF 4 AAAVmRAAEAAAAV7AAx 5 AAAVmRAAEAAAAV7AAa 6 AAAVmRAAEAAAAV7AAV 通过以上的输出可以看出这个时候是按照主键列来排序的,数据是有序的。 这个时候我们可以分成两个场景来测试。一个是没有主键/唯一性索引,一个是存在主键/唯一性索引 先删除主键 SQL> alter table test_lock drop primary key; Table altered. 测试没有主键/唯一性索引的场景,还是按照rowid排列。 SQL> select object_id ,rowid from test_lock where rownum<6; OBJECT_ID ROWID ---------- ------------------ 20 AAAVmRAAEAAAAV7AAA 46 AAAVmRAAEAAAAV7AAB 28 AAAVmRAAEAAAAV7AAC 15 AAAVmRAAEAAAAV7AAD 29 AAAVmRAAEAAAAV7AAE 我们更新一条数据,object_id=20的记录。 SQL> update test_lock set object_id=1000123 where object_id=20; 1 row updated. rownum是否有其它的变化呢。 SQL> select object_id ,rowid from test_lock where rownum<6; OBJECT_ID ROWID ---------- ------------------ 1000123 AAAVmWAAEAAAEUbAAA 46 AAAVmWAAEAAAEUbAAB 28 AAAVmWAAEAAAEUbAAC 15 AAAVmWAAEAAAEUbAAD 29 AAAVmWAAEAAAEUbAAE 可以看出这个结果是显而易见的。 再更新一条记录。 SQL> update test_lock set object_id=10001223 where object_id=46; 1 row updated. 查看rownum的情况, SQL> update test_lock set object_id=10001223 where object_id=46; 1 row updated. SQL> select object_id ,rowid from test_lock where rownum<6; OBJECT_ID ROWID ---------- ------------------ 1000123 AAAVmWAAEAAAEUbAAA 10001223 AAAVmWAAEAAAEUbAAB 28 AAAVmWAAEAAAEUbAAC 15 AAAVmWAAEAAAEUbAAD 29 AAAVmWAAEAAAEUbAAE 这些都是预期的结果,可见rownum还是有规律的。 我们切换会话到会话2 会话2: 查看rownum的情况,这个时候可以看到rownum的输出还是有规律可循的。只是为了保证一致性读,数据不同,但是rowid还是一致的。 SQL> select object_id ,rowid from test_lock where rownum<6; OBJECT_ID ROWID ---------- ------------------ 20 AAAVmWAAEAAAEUbAAA 46 AAAVmWAAEAAAEUbAAB 28 AAAVmWAAEAAAEUbAAC 15 AAAVmWAAEAAAEUbAAD 29 AAAVmWAAEAAAEUbAAE 看来不存在主键/唯一性索引的情况下,没有给我们带来太多惊喜,虽然有基本规律但是似乎都是意料之中。 我们来看看存在主键/唯一性索引的情况。 会话1: 我们创建唯一性索引。 SQL> create unique index ind_test_lock on test_lock(object_id); Index created. 这个时候rownum是按照对应的索引列来排列的,数据是有序的。 SQL> select object_id ,rowid from test_lock where rownum<6; OBJECT_ID ROWID ---------- ------------------ 2 AAAVmWAAEAAAEUbAAw 3 AAAVmWAAEAAAEUbAAF 4 AAAVmWAAEAAAEUbAAx 5 AAAVmWAAEAAAEUbAAa 6 AAAVmWAAEAAAEUbAAV 然后照例更新一行数据,object_id=2来看看。 update test_lock set object_id=10023420 where object_id=2; 可以看到rownum的情况,object_id是从下一行开始,即object_id=3 SQL> select object_id ,rowid from test_lock where rownum<6; OBJECT_ID ROWID ---------- ------------------ 3 AAAVmWAAEAAAEUbAAF 4 AAAVmWAAEAAAEUbAAx 5 AAAVmWAAEAAAEUbAAa 6 AAAVmWAAEAAAEUbAAV 7 AAAVmWAAEAAAEUbAAR 这就有点意思了,这是不是有规律可循呢,我们再更新object_id=3的行 SQL> update test_lock set object_id=10023421 where object_id=3; 1 row updated. 再次查看rownum的情况,发现是从object_id=4开始输出了。 SQL> select object_id ,rowid from test_lock where rownum<6; OBJECT_ID ROWID ---------- ------------------ 4 AAAVmWAAEAAAEUbAAx 5 AAAVmWAAEAAAEUbAAa 6 AAAVmWAAEAAAEUbAAV 7 AAAVmWAAEAAAEUbAAR 8 AAAVmWAAEAAAEUbAAk 我们切换到会话2来看看数据情况。 会话2: SQL> select object_id ,rowid from test_lock where rownum<6; OBJECT_ID ROWID ---------- ------------------ 2 AAAVmWAAEAAAEUbAAw 3 AAAVmWAAEAAAEUbAAF 4 AAAVmWAAEAAAEUbAAx 5 AAAVmWAAEAAAEUbAAa 6 AAAVmWAAEAAAEUbAAV 可以看到会话2还是保留了原有的数据输出格式,还是从object_id=2开始。 切换回会话1: 会话1: 提交事务 SQL> commit; Commit complete. 这个时候下标就是从object_id=4开始了,在会话2中也是一样的输出结果。 SQL> select object_id ,rowid from test_lock where rownum<6; OBJECT_ID ROWID ---------- ------------------ 4 AAAVmWAAEAAAEUbAAx 5 AAAVmWAAEAAAEUbAAa 6 AAAVmWAAEAAAEUbAAV 7 AAAVmWAAEAAAEUbAAR 8 AAAVmWAAEAAAEUbAAk 我们来更新中间的一行数据,比如object_id=6看看是否依旧有规律。 SQL> update test_lock set object_id=10023422 where object_id=6; 1 row updated. 这个时候查看,发现object_id=6的记录好像从链表中删除了一样。 SQL> select object_id ,rowid from test_lock where rownum<6; OBJECT_ID ROWID ---------- ------------------ 4 AAAVmWAAEAAAEUbAAx 5 AAAVmWAAEAAAEUbAAa 7 AAAVmWAAEAAAEUbAAR 8 AAAVmWAAEAAAEUbAAk 9 AAAVmWAAEAAAEUbAAN 如果此时我们rollback SQL> rollback; Rollback complete. 这个时候object_id=6的数据又回来了。 SQL> select object_id ,rowid from test_lock where rownum<6; OBJECT_ID ROWID ---------- ------------------ 4 AAAVmWAAEAAAEUbAAx 5 AAAVmWAAEAAAEUbAAa 6 AAAVmWAAEAAAEUbAAV 7 AAAVmWAAEAAAEUbAAR 8 AAAVmWAAEAAAEUbAAk 由此可以看出rowid还是和数据的存储有很大的关系,和事务是有关联的,总之还是有一定的规律可循的。