ORACLE optimization---return table (TABLE ACCESS BY INDEX ROWID)

When an index is created on a column, the index contains the key value of the column and the rowid of the row corresponding to the key value. Accessing the data in the table through the rowid recorded in the index is called back to the table. The return table is generally a single block read. Too many times to return the table will seriously affect the SQL performance. If the number of times to return the table is too many, index scan should not be performed, and full table scan should be performed directly.

When performing SQL optimization, be sure to pay attention to the number of times the table is returned! In particular, pay attention to the number of physical I/Os returned to the table!

SQL> select * from test where owner = 'SYS';

30812 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 3932013684

-----------------------------------------------------------------------------------------
| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |           |  2499 |   236K|    73   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TEST      |  2499 |   236K|    73   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IDX_OWNER |  2499 |       |     6   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("OWNER"='SYS')


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
       4927  consistent gets
         69  physical reads
          0  redo size
    3502852  bytes sent via SQL*Net to client
      23117  bytes received via SQL*Net from client
       2056  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
      30812  rows processed

SQL> 
 

The bold part in the execution plan ( TABLE ACCESS BY INDEX ROWID ) is the return table. How many rows of data are returned by the index. How many times to return the table, each time the table is returned is a single block read (because one rowid corresponds to a data block). The SQL returns 30812 rows of data, so it takes a total of 30812 times to return the table.

Think about it: Is the performance of the above execution plan consumed in the index scan or in the return table?

In order to get the answer, please experiment in SQLPLUS. To eliminate the impact of the arraysize parameter on logical reads, set arraysize=5000. arraysize indicates how many rows of data the Oracle server transmits to the client each time, the default is 15. If a block has 150 rows of data, then the block will be read 10 times, since only 15 rows of data are transferred to the client each time, the logical read will be amplified. After setting arraysize=5000, the problem of a block being read n times will not occur.

 

SQL> set pagesize 100
SQL> set line 200
SQL> set arraysize 5000
SQL> set autot trace
SQL> select owner from test where owner='SYS';

30812 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 1086061979

----------------------------------------------------------------------------------
| Id  | Operation            | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |           | 30812 |   180K|    48   (0)| 00:00:01 |
|*  1 |  INDEX FAST FULL SCAN| IDX_OWNER | 30812 |   180K|    48   (0)| 00:00:01 |
----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("OWNER"='SYS')


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
        186  consistent gets
          0  physical reads
          0  redo size
     155727  bytes sent via SQL*Net to client
        589  bytes received via SQL*Net from client
          8  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
      30812  rows processed

SQL> 

 

From the above experiment, it can be seen that the index scan only consumes 186 logical reads.

 

SQL> set autot off
SQL> select count(distinct dbms_rowid.rowid_block_number(rowid)) blocks from test where owner = 'SYS';

    BLOCKS
----------
       798

SQL> 

 

The performance of this SQL is indeed mostly lost in the return table.

Even worse: assuming that 30,812 pieces of data are in different data blocks, and the table is not cached in the buffer cache, it takes a total of 30,812 physical I/Os to return the table, which is terrible.

In the case where it is unavoidable to return to the table, if the index returns too much data, it will inevitably lead to too many times of returning to the table, resulting in serious performance degradation.

What kind of SQL must be returned to the table?

select * from table where ...

Such SQL must be returned to the table, so we must strictly prohibit the use of select *. What kind of SQL does not need to return to the table?

select count(*) from table

Such SQL does not require a return table.

When the column to be queried is also included in the index, there is no need to return to the table at this time, so we often build a composite index to eliminate the return to the table, thereby improving query performance.

When a SQL has multiple filter conditions but only one column or part of the column is indexed, at this time, the table will be returned to the table and then filtered (TABLE ACCESS BY INDEX ROWID is preceded by "*"), and a combined index needs to be created to eliminate the return to the table. Then filter to improve query performance.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324148579&siteId=291194637