• 关于逻辑读问题


    SQL> create table test(id int,name char(10));
    
    Table created.
    
    SQL> begin
      2  for i in 1 .. 10000
      3  loop
      4  insert into test values(i,'a'||i);
      5  end loop;
      6  commit;
      7  end ;
      8  /
    
    PL/SQL procedure successfully completed.
    SQL> select count(*) from test;
    
      COUNT(*)
    ----------
         10000
    
    SQL> create index test_idx1 on test(id);
    
    Index created.
    
    
    BEGIN
      DBMS_STATS.GATHER_TABLE_STATS(ownname          => 'TEST',
                                    tabname          => 'TEST',
                                    estimate_percent => 100,
                                    method_opt       => 'for all columns size skewonly',
                                    no_invalidate    => FALSE,
                                    degree           => 1,
                                    cascade          => TRUE);
    END;
    
    SQL>  select count(distinct dbms_rowid.rowid_block_number(rowid)) from test;
    
    COUNT(DISTINCTDBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID))
    ---------------------------------------------------
    						 28
    
    
    SQL> select count(distinct dbms_rowid.rowid_block_number(rowid)) from test where id<300;
    
    COUNT(DISTINCTDBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID))
    ---------------------------------------------------
    						  1
    
    总共存放在28个块里,其中id<300的存放在一个块里
    
    SQL> select * from test where id<300;
    
    299 rows selected.
    
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 2624864549
    
    -----------------------------------------------------------------------------------------
    | Id  | Operation		    | Name	| Rows	| Bytes | Cost (%CPU)| Time	|
    -----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT	    |		|   299 |  4485 |     3   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| TEST	|   299 |  4485 |     3   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN	    | TEST_IDX1 |   299 |	|     2   (0)| 00:00:01 |
    -----------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("ID"<300)
    
    
    Statistics
    ----------------------------------------------------------
    	  0  recursive calls
    	  0  db block gets
    	 43  consistent gets
    	  0  physical reads
    	  0  redo size
           8853  bytes sent via SQL*Net to client
    	628  bytes received via SQL*Net from client
    	 21  SQL*Net roundtrips to/from client
    	  0  sorts (memory)
    	  0  sorts (disk)
    
    逻辑读是43 那43是怎么来的呢?
    SQL> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
    
    PLAN_TABLE_OUTPUT
    ------------------------------------------------------------------------------------------------------------------------------------------------------------
    
    --------------------------------------------
    SQL_ID	7vthtgk378xdk, child number 1
    -------------------------------------
    select * from test where id<300
    
    Plan hash value: 2624864549
    
    ---------------------------------------------------------------------------------------------------
    | Id  | Operation		    | Name	| Starts | E-Rows | A-Rows |   A-Time	| Buffers |
    ---------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT	    |		|      1 |	  |    299 |00:00:00.01 |      43 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| TEST	|      1 |    299 |    299 |00:00:00.01 |      43 |
    |*  2 |   INDEX RANGE SCAN	    | TEST_IDX1 |      1 |    299 |    299 |00:00:00.01 |      22 |
    ---------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("ID"<300)
    
    
    19 rows selected.
    
    查看下索引的高度:
    SQL> select index_name, PREFIX_LENGTH, BLEVEL, LEAF_BLOCKS from user_indexes where index_name='TEST_IDX1';
    
    INDEX_NAME		       PREFIX_LENGTH	 BLEVEL LEAF_BLOCKS
    ------------------------------ ------------- ---------- -----------
    TEST_IDX1					      1 	 21
    
    可以看到索引高度为1,叶子节点有21个块
    
    BLEVEL* NUMBER   B*-Tree level: depth of the index from its root block to its leaf blocks. A depth of 0 indicates that the root block and leaf block are the 
    
    same.
    
    最底层的索引块(叶块(leaf block))存储了被索引的数据值,以及对应的 rowid。一个leaf block存储多个被索引的数据值
    
    
    因为ID<300的表数据都在一个块里,那么是不是回表就不会增加逻辑读,也就是说访问表的逻辑读始终为1,那么推测访问索引的逻辑读为42
    
    那42是怎么来的呢?表示疑问?
    从set autot trace看是索引读了1+21=22个,回表后逻辑读变为43 那回表都干了些什么呢 增加了21个逻辑读?21个逻辑读难道是正好回表21次,那不符合前面的逻辑?
    
    
    
    
    

  • 相关阅读:
    sublime Text 正则替换
    sublime Text 正则替换
    C# 解析 sln 文件
    PHP array_flip() 函数
    PHP array_filter() 函数
    PHP array_fill_keys() 函数
    PHP array_fill() 函数
    PHP array_diff_ukey() 函数
    51nod1355 斐波那契的最小公倍数
    C# 解析 sln 文件
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13352438.html
Copyright © 2020-2023  润新知