写入值顺序和乱序对数据访问的影响

数据写入到表时, 写入值顺序和乱序对数据访问的影响
2017-12-13 听了高斌的讲解, 自己做了实验,验证了下面的结论:

当普通 heap表,即堆表, 在写入值时,被索引值的写入顺序会影响访问性能 :
1. 当写入值是顺序的时候, 表记录也是在 block 里按照顺序写入, 即  id =  1,2,3,4,5 记录 会写入 第一个 block ,当第一个block写满后 ,
顺序写入下一个block, 这个顺序指的是磁盘访问顺序 。

2. 当写入值是乱序时, 乱序表记录就会存放在顺序的block里面, 差别很大的 id 值的 几条记录放在同一个块里面 。

3. 当 使用索引的时候, 被索引的值是根据 B* 树来进行从小到大排序的, 
  上述 情况 1的时候, 多个索引块指向 一个数据块 , 
  上述情况2 的时候, 一个索引块里面的值 指向 多个 表 数据块

4. 分区以后, 打破 数据块 热点

5. reverse 键值后 打破了索引热块


drop table testseq ;
drop table testsca ;

create table testseq ( id number(18) , fname varchar(1000) ) ;
create index ind_seq on testseq(id) ;

create table testsca ( id number(18) , fname varchar(1000) ) ;
create index ind_sca on testsca(id) ;


---- 写入1 万行数据,
 

SQL> select * from v$version ;
BANNER
------------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
PL/SQL Release 12.2.0.1.0 - Production
CORE    12.2.0.1.0      Production
TNS for 64-bit Windows: Version 12.2.0.1.0 - Production
NLSRTL Version 12.2.0.1.0 - Production

SQL> select extent_id , bytes, blocks from user_extents where segment_name='TESTSEQ' ;

no rows selected

SQL> select extent_id , bytes , blocks from user_extents where segment_name='TESTSCA' ;

no rows selected

SQL>


begin

    for i in 1..10000  loop
        insert into testseq ( id , fname ) values ( i , dbms_random.String('a', 1000 ) ) ;
    
    end loop ;
    commit;
    
end;
/

 

Elapsed: 00:00:44.70


begin

    for i in 1..10000  loop
        insert into testsca ( id , fname ) values ( dbms_random.value(1, 10000 ) , dbms_random.String('a', 1000 ) ) ;
    
    end loop ;
    commit;
    
end;
/

Elapsed: 00:00:45.82







 select extent_id , bytes, blocks from user_extents where segment_name='TESTSEQ' ;

 EXTENT_ID      BYTES     BLOCKS
---------- ---------- ----------
         0      65536          8
         1      65536          8
         2      65536          8
         3      65536          8
         4      65536          8
         5      65536          8
         6      65536          8
         7      65536          8
         8      65536          8
         9      65536          8
        10      65536          8

 EXTENT_ID      BYTES     BLOCKS
---------- ---------- ----------
        11      65536          8
        12      65536          8
        13      65536          8
        14      65536          8
        15      65536          8
        16    1048576        128
        17    1048576        128
        18    1048576        128
        19    1048576        128
        20    1048576        128
        21    1048576        128

 EXTENT_ID      BYTES     BLOCKS
---------- ---------- ----------
        22    1048576        128
        23    1048576        128
        24    1048576        128
        25    1048576        128
        26    1048576        128

27 rows selected.

select sum(blocks) from user_extents where segment_name='TESTSEQ' ;
SUM(BLOCKS)
-----------
       1536

exec dbms_stats.gather_table_stats(user,'TESTSEQ');    
analyze table TESTSEQ compute statistics;        
select num_rows, blocks, empty_blocks, avg_row_len from user_tables where table_name = 'TESTSEQ' ;
  NUM_ROWS     BLOCKS EMPTY_BLOCKS AVG_ROW_LEN
---------- ---------- ------------ -----------
     10000       1504           32        1010

一共 1536 block 分配给表,      32 是空的 1504 是使用的 ,

1504 + 32 = 1536

select id,  rowid from testseq  where rownum < 50  order by id   ;  
select id, substr(rowid,10,6) blocknumber , substr(rowid,16,3) rownumber     from testseq  where rownum < 100  order by id   ;  
       

        ID BLOCKNUMBE ROWNUMBER
---------- ---------- ----------
         1 AAAc7u     AAA
         2 AAAc7u     AAB
         3 AAAc7u     AAC
         4 AAAc7u     AAD
         5 AAAc7u     AAE
         6 AAAc7u     AAF
         7 AAAc7u     AAG
         8 AAAc7v     AAA
         9 AAAc7v     AAB
        10 AAAc7v     AAC
        11 AAAc7v     AAD

        ID BLOCKNUMBE ROWNUMBER
---------- ---------- ----------
        12 AAAc7v     AAE
        13 AAAc7v     AAF
        14 AAAc7v     AAG
        15 AAAc7r     AAA
        16 AAAc7r     AAB
        17 AAAc7r     AAC
        18 AAAc7r     AAD
        19 AAAc7r     AAE
        20 AAAc7r     AAF
        21 AAAc7r     AAG
        22 AAAc7s     AAA

        ID BLOCKNUMBE ROWNUMBER
---------- ---------- ----------
        23 AAAc7s     AAB
        24 AAAc7s     AAC
        25 AAAc7s     AAD
        26 AAAc7s     AAE
        27 AAAc7s     AAF
        28 AAAc7s     AAG
        29 AAAc7t     AAA
        30 AAAc7t     AAB
        31 AAAc7t     AAC
        32 AAAc7t     AAD
        33 AAAc7t     AAE

        ID BLOCKNUMBE ROWNUMBER
---------- ---------- ----------
        34 AAAc7t     AAF
        35 AAAc7t     AAG
        36 AAAc74     AAA
        37 AAAc74     AAB
        38 AAAc74     AAC
        39 AAAc74     AAD
        40 AAAc74     AAE
        41 AAAc74     AAF
        42 AAAc74     AAG
        43 AAAc76     AAA
        44 AAAc76     AAB

        ID BLOCKNUMBE ROWNUMBER
---------- ---------- ----------
        45 AAAc76     AAC
        46 AAAc76     AAD
        47 AAAc76     AAE
        48 AAAc76     AAF
        49 AAAc76     AAG
        50 AAAc77     AAA
        51 AAAc77     AAB
        52 AAAc77     AAC
        53 AAAc77     AAD
        54 AAAc77     AAE
        55 AAAc77     AAF

        ID BLOCKNUMBE ROWNUMBER
---------- ---------- ----------
        56 AAAc77     AAG
        57 AAAc78     AAA
        58 AAAc78     AAB
        59 AAAc78     AAC
        60 AAAc78     AAD
        61 AAAc78     AAE
        62 AAAc78     AAF
        63 AAAc78     AAG
        64 AAAc79     AAA
        65 AAAc79     AAB
        66 AAAc79     AAC

        ID BLOCKNUMBE ROWNUMBER
---------- ---------- ----------
        67 AAAc79     AAD
        68 AAAc79     AAE
        69 AAAc79     AAF
        70 AAAc79     AAG
        71 AAAc7+     AAA
        72 AAAc7+     AAB
        73 AAAc7+     AAC
        74 AAAc7+     AAD
        75 AAAc7+     AAE
        76 AAAc7+     AAF
        77 AAAc7+     AAG

        ID BLOCKNUMBE ROWNUMBER
---------- ---------- ----------
        78 AAAc7/     AAA
        79 AAAc7/     AAB
        80 AAAc7/     AAC
        81 AAAc7/     AAD
        82 AAAc7/     AAE
        83 AAAc7/     AAF
        84 AAAc7/     AAG
        85 AAAc75     AAA
        86 AAAc75     AAB
        87 AAAc75     AAC
        88 AAAc75     AAD

        ID BLOCKNUMBE ROWNUMBER
---------- ---------- ----------
        89 AAAc75     AAE
        90 AAAc75     AAF
        91 AAAc75     AAG
        92 AAAdoC     AAA
       134 AAAdoB     AAA
       135 AAAdoB     AAB
       136 AAAdoB     AAC
       137 AAAdoB     AAD
       138 AAAdoB     AAE
       139 AAAdoB     AAF
       140 AAAdoB     AAG
       
       
select distinct blocknumber from ( select id, substr(rowid,10,6) blocknumber , substr(rowid,16,3) rownumber     from testseq  where rownum < 100  order by id )  ;         
       
顺序写入的数据基本按照顺序在一个数据块里面, 当根据id的范围来选择数据时, 例如 id > 1 and id < 100 ,     要读 15 个块
BLOCKNUMBE
----------
AAAc7s
AAAc7r
AAAc76
AAAc74
AAAc75
AAAdoB
AAAc7u
AAAc7v
AAAc78
AAAc7+
AAAdoC

BLOCKNUMBE
----------
AAAc77
AAAc7/
AAAc7t
AAAc79

15 rows selected.
   
       
       
       
       
       
       
       
       
select extent_id , bytes , blocks from user_extents where segment_name='TESTSCA' ;
 EXTENT_ID      BYTES     BLOCKS
---------- ---------- ----------
         0      65536          8
         1      65536          8
         2      65536          8
         3      65536          8
         4      65536          8
         5      65536          8
         6      65536          8
         7      65536          8
         8      65536          8
         9      65536          8
        10      65536          8

 EXTENT_ID      BYTES     BLOCKS
---------- ---------- ----------
        11      65536          8
        12      65536          8
        13      65536          8
        14      65536          8
        15      65536          8
        16    1048576        128
        17    1048576        128
        18    1048576        128
        19    1048576        128
        20    1048576        128
        21    1048576        128

 EXTENT_ID      BYTES     BLOCKS
---------- ---------- ----------
        22    1048576        128
        23    1048576        128
        24    1048576        128
        25    1048576        128
        26    1048576        128

27 rows selected.


select sum(blocks) from user_extents where segment_name='TESTSCA' ;

SUM(BLOCKS)
-----------
       1536
       
exec dbms_stats.gather_table_stats(user,'TESTSCA');    
analyze table TESTSCA compute statistics;        
select num_rows, blocks, empty_blocks, avg_row_len from user_tables where table_name = 'TESTSCA' ;       
  NUM_ROWS     BLOCKS EMPTY_BLOCKS AVG_ROW_LEN
---------- ---------- ------------ -----------
     10000       1504           32        1011


select id,  rowid from testsca  where rownum < 100  order by id   ;  

select id, substr(rowid,10,6) blocknumber , substr(rowid,16,3) rownumber     from testsca  where rownum < 100  order by id ;
        ID BLOCKNUMBE ROWNUMBER
---------- ---------- ----------
        90 AAAeC/     AAD
       210 AAAeDK     AAA
       285 AAAeDP     AAG
       298 AAAeC7     AAA
       657 AAAeC7     AAF
       740 AAAeDJ     AAA
       871 AAAeDP     AAA
       882 AAAeDI     AAB
      1022 AAAeC8     AAE
      1028 AAAeC+     AAG
      1082 AAAeC/     AAG

        ID BLOCKNUMBE ROWNUMBER
---------- ---------- ----------
      1142 AAAeDO     AAC
      1589 AAAeC8     AAA
      1745 AAAeC/     AAF
      1774 AAAeC/     AAA
      1886 AAAeC9     AAE
      2130 AAAeDK     AAF
      2259 AAAeC8     AAD
      2352 AAAeDJ     AAD
      2441 AAAeDI     AAG
      2615 AAAeDR     AAC
      2759 AAAeC7     AAD

        ID BLOCKNUMBE ROWNUMBER
---------- ---------- ----------
      2768 AAAeDM     AAG
      2832 AAAeC/     AAB
      2975 AAAeDI     AAA
      3184 AAAeDK     AAC
      3195 AAAeDN     AAA
      3229 AAAeDR     AAA
      3311 AAAeC8     AAB
      3430 AAAeDI     AAE
      3506 AAAeC8     AAF
      3659 AAAeDP     AAD
      3831 AAAeC+     AAB

        ID BLOCKNUMBE ROWNUMBER
---------- ---------- ----------
      3879 AAAeC+     AAA
      3980 AAAeDM     AAA
      4202 AAAeC/     AAE
      4291 AAAeDO     AAG
      4372 AAAeDL     AAD
      4437 AAAeDJ     AAG
      4519 AAAeC7     AAB
      4541 AAAeC8     AAC
      4588 AAAeDN     AAD
      4674 AAAeDM     AAB
      4715 AAAeC7     AAG

        ID BLOCKNUMBE ROWNUMBER
---------- ---------- ----------
      4772 AAAeC+     AAE
      4942 AAAeC8     AAG
      5051 AAAeDN     AAF
      5054 AAAeDI     AAC
      5107 AAAeC/     AAC
      5238 AAAeDO     AAE
      5289 AAAeC7     AAE
      5318 AAAeDJ     AAF
      5447 AAAeDL     AAE
      5468 AAAeDO     AAB
      5477 AAAeC9     AAA

        ID BLOCKNUMBE ROWNUMBER
---------- ---------- ----------
      5514 AAAeDR     AAE
      5624 AAAeC9     AAG
      5908 AAAeDK     AAE
      5934 AAAeDJ     AAB
      6318 AAAeC+     AAF
      6371 AAAeDJ     AAC
      6510 AAAeDS     AAA
      6568 AAAeDN     AAC
      6668 AAAeDO     AAF
      6763 AAAeDP     AAF
      6845 AAAeDL     AAF

        ID BLOCKNUMBE ROWNUMBER
---------- ---------- ----------
      6850 AAAeDL     AAG
      6937 AAAeDR     AAF
      7054 AAAeDL     AAA
      7127 AAAeDJ     AAE
      7256 AAAeC9     AAB
      7303 AAAeDN     AAB
      7348 AAAeDP     AAC
      7455 AAAeDR     AAD
      7504 AAAeDM     AAF
      7574 AAAeC9     AAF
      7751 AAAeDK     AAG

        ID BLOCKNUMBE ROWNUMBER
---------- ---------- ----------
      7869 AAAeDI     AAF
      8018 AAAeDO     AAD
      8136 AAAeC9     AAD
      8264 AAAeDK     AAD
      8433 AAAeDK     AAB
      8527 AAAeDN     AAE
      8559 AAAeC7     AAC
      8559 AAAeC+     AAC
      8586 AAAeDM     AAD
      8659 AAAeDO     AAA
      8729 AAAeC9     AAC

        ID BLOCKNUMBE ROWNUMBER
---------- ---------- ----------
      8812 AAAeDP     AAE
      8813 AAAeDR     AAG
      8841 AAAeDR     AAB
      8901 AAAeC+     AAD
      8968 AAAeDL     AAB
      9108 AAAeDI     AAD
      9330 AAAeDP     AAB
      9396 AAAeDN     AAG
      9513 AAAeDM     AAC
      9702 AAAeDM     AAE
      9783 AAAeDL     AAC
    
    
select distinct blocknumber from ( select id, substr(rowid,10,6) blocknumber , substr(rowid,16,3) rownumber     from testsca  where rownum < 100  order by id )  ;  
BLOCKNUMBE
----------
AAAeC+
AAAeDR
AAAeC/
AAAeDK
AAAeDO
AAAeC8
AAAeDL
AAAeDP
AAAeDJ
AAAeC9
AAAeDI

BLOCKNUMBE
----------
AAAeDN
AAAeDS
AAAeC7
AAAeDM

15 rows selected.

同样写入 15 个块,  但是 访问时 被索引的值是分布在多个数据块里面进行排序。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/16993226/viewspace-2148681/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/16993226/viewspace-2148681/

你可能感兴趣的:(写入值顺序和乱序对数据访问的影响)