【基礎篇基本原理】資料訪問方式

yellowlee發表於2010-07-19

從前面一些測試中的執行計劃可以看到一些有關資料的訪問方式,比如Full Table Scan, Index Unique Scan, Index Range Scan, Index Full Scan, Index Fast Full Scan, Index Skip Scan, Bitmap index等。

1,Table Access by user rowid

SQL> select rowid, a.object_id

  2    from test.t_test_clusterfactor1 a

  3   where rowid = 'AAAP3sAAEAAAATUAAA';

 

ROWID               OBJECT_ID

------------------ ----------

AAAP3sAAEAAAATUAAA          2

 

 

Execution Plan

----------------------------------------------------------

Plan hash value: 2983979101

 

--------------------------------------------------------------------------------

--------------------

 

| Id  | Operation                  | Name                  | Rows  | Bytes | Cos

t (%CPU)| Time     |

 

--------------------------------------------------------------------------------

--------------------

 

|   0 | SELECT STATEMENT           |                       |     1 |    15 |

 1   (0)| 00:00:01 |

 

|   1 |  TABLE ACCESS BY USER ROWID| T_TEST_CLUSTERFACTOR1 |     1 |    15 |

 1   (0)| 00:00:01 |

 

--------------------------------------------------------------------------------

--------------------

 

 

 

Statistics

----------------------------------------------------------

          1  recursive calls

          0  db block gets

          1  consistent gets

          0  physical reads

          0  redo size

        484  bytes sent via SQL*Net to client

        400  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

          1  rows processed

 

SQL>

注意到統計資訊,只有一個consistent gets,這一個一致性讀也比較好理解,只需要一次讀取即可以獲得資料。這種方式是訪問資料最快的方式。

 

2,Table Access full

全表掃描一次性讀取多個資料塊,每個塊讀取資料到高水位線處。

下面的語句中的rownum = 1也可以改成 <= 1,在oracle 10g版本下面這兩個是一樣的。

SQL> select rowid, a.object_id

  2    from test.t_test_clusterfactor1 a

  3   where rownum = 1;

 

ROWID               OBJECT_ID

------------------ ----------

AAAP3sAAEAAAATUAAA          2

 

 

Execution Plan

----------------------------------------------------------

Plan hash value: 2839102670

 

--------------------------------------------------------------------------------

------------

 

| Id  | Operation          | Name                  | Rows  | Bytes | Cost (%CPU)

| Time     |

 

--------------------------------------------------------------------------------

------------

 

|   0 | SELECT STATEMENT   |                       |     1 |    15 |     2   (0)

| 00:00:01 |

 

|*  1 |  COUNT STOPKEY     |                       |       |       |

|          |

 

|   2 |   TABLE ACCESS FULL| T_TEST_CLUSTERFACTOR1 |     1 |    15 |     2   (0)

| 00:00:01 |

 

--------------------------------------------------------------------------------

------------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   1 - filter(ROWNUM=1)

 

 

Statistics

----------------------------------------------------------

          1  recursive calls

          0  db block gets

          4  consistent gets

          0  physical reads

          0  redo size

        484  bytes sent via SQL*Net to client

        400  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

          1  rows processed

 

SQL>

 

3,index unique scan

索引唯一掃描,針對唯一索引,這種方式訪問資料比較快,每個索引鍵值對應一個rowid,而從一致性讀的數量也可以看到。

SQL> create table t_test_uni_1 as select * from dba_objects;

 

Table created.

 

SQL> create unique index idx_test_uni_1 on t_test_uni_1(object_id);

 

Index created.

 

SQL> select object_id from t_test_uni_1 a where a.object_id = 2;

 

 OBJECT_ID

----------

         2

 

 

Execution Plan

----------------------------------------------------------

Plan hash value: 2691534793

 

--------------------------------------------------------------------------------

----

 

| Id  | Operation         | Name           | Rows  | Bytes | Cost (%CPU)| Time

   |

 

--------------------------------------------------------------------------------

----

 

|   0 | SELECT STATEMENT  |                |     1 |    13 |     1   (0)| 00:00:

01 |

 

|*  1 |  INDEX UNIQUE SCAN| IDX_TEST_UNI_1 |     1 |    13 |     1   (0)| 00:00:

01 |

 

--------------------------------------------------------------------------------

----

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   1 - access("A"."OBJECT_ID"=2)

 

 

Statistics

----------------------------------------------------------

          1  recursive calls

          0  db block gets

          2  consistent gets

          1  physical reads

          0  redo size

        412  bytes sent via SQL*Net to client

        400  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

          1  rows processed

 

SQL>

 

4,index range scan

普通索引常用的訪問方式,先通過給定的數值範圍找到相應索引的branch block,在對應的leaf地址中查詢leaf block,再從找到的這些leaf block中找滿足的rowid

SQL> select object_id from t_test_uni_1 a where a.object_id < 3;

 

 

Execution Plan

----------------------------------------------------------

Plan hash value: 842571182

 

--------------------------------------------------------------------------------

---

 

| Id  | Operation        | Name           | Rows  | Bytes | Cost (%CPU)| Time

  |

 

--------------------------------------------------------------------------------

---

 

|   0 | SELECT STATEMENT |                |     1 |    13 |     2   (0)| 00:00:0

1 |

 

|*  1 |  INDEX RANGE SCAN| IDX_TEST_UNI_1 |     1 |    13 |     2   (0)| 00:00:0

1 |

 

--------------------------------------------------------------------------------

---

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   1 - access("A"."OBJECT_ID"<3)

 

Note

-----

   - dynamic sampling used for this statement

 

 

Statistics

----------------------------------------------------------

          0  recursive calls

          0  db block gets

          3  consistent gets

          0  physical reads

          0  redo size

        412  bytes sent via SQL*Net to client

        400  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

          1  rows processed

 

SQL>

 

5,index fast full scan

 

SQL> select object_id from t_test_uni_1 a where a.object_id > 2;

 

55048 rows selected.

 

 

Execution Plan

----------------------------------------------------------

Plan hash value: 100569850

 

--------------------------------------------------------------------------------

-------

 

| Id  | Operation            | Name           | Rows  | Bytes | Cost (%CPU)| Tim

e     |

 

--------------------------------------------------------------------------------

-------

 

|   0 | SELECT STATEMENT     |                | 55048 |   215K|    28   (4)| 00:

00:01 |

 

|*  1 |  INDEX FAST FULL SCAN| IDX_TEST_UNI_1 | 55048 |   215K|    28   (4)| 00:

00:01 |

 

--------------------------------------------------------------------------------

-------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   1 - filter("A"."OBJECT_ID">2)

 

 

Statistics

----------------------------------------------------------

          0  recursive calls

          0  db block gets

       3784  consistent gets

          0  physical reads

          0  redo size

     797531  bytes sent via SQL*Net to client

      40759  bytes received via SQL*Net from client

       3671  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

      55048  rows processed

 

SQL>                                                           

 

上面的例子中,優化器認為FFS要比TFC快,在FFS期間,oracle讀取B樹索引上的所有葉塊,且可以一次性讀取多個塊,如果表查詢中所有的列都包括在了索引中,就有可能使用FFS,當然也可以使用hint來選擇FFS。下面看看使用不同方式訪問索引的例子:

SQL> create index idx_test_uni_1_owner_id on t_test_uni_1(owner,data_object_id);

 

Index created.

 

SQL>

 

SQL> select owner,data_object_id from t_test_uni_1 a

  2  where data_object_id > 3;

 

5343 rows selected.

 

 

Execution Plan

----------------------------------------------------------

Plan hash value: 3246279645

 

--------------------------------------------------------------------------------

----------------

 

| Id  | Operation            | Name                    | Rows  | Bytes | Cost (%

CPU)| Time     |

 

--------------------------------------------------------------------------------

----------------

 

|   0 | SELECT STATEMENT     |                         |  5361 | 37527 |    33

 (4)| 00:00:01 |

 

|*  1 |  INDEX FAST FULL SCAN| IDX_TEST_UNI_1_OWNER_ID |  5361 | 37527 |    33

 (4)| 00:00:01 |

 

--------------------------------------------------------------------------------

----------------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   1 - filter("DATA_OBJECT_ID">3)

 

 

Statistics

----------------------------------------------------------

          1  recursive calls

          0  db block gets

        503  consistent gets

          0  physical reads

          0  redo size

      97247  bytes sent via SQL*Net to client

       4316  bytes received via SQL*Net from client

        358  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

       5343  rows processed

 

SQL>

SQL> select owner,data_object_id from t_test_uni_1 a

  2  where data_object_id = 3;

 

 

Execution Plan

----------------------------------------------------------

Plan hash value: 3105119147

 

--------------------------------------------------------------------------------

--------------------

 

| Id  | Operation                   | Name                 | Rows  | Bytes | Cos

t (%CPU)| Time     |

 

--------------------------------------------------------------------------------

--------------------

 

|   0 | SELECT STATEMENT            |                      |     1 |     7 |

 2   (0)| 00:00:01 |

 

|   1 |  TABLE ACCESS BY INDEX ROWID| T_TEST_UNI_1         |     1 |     7 |

 2   (0)| 00:00:01 |

 

|*  2 |   INDEX RANGE SCAN          | IDX_TEST_UNI_1_DATAO |     1 |       |

 1   (0)| 00:00:01 |

 

--------------------------------------------------------------------------------

--------------------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   2 - access("DATA_OBJECT_ID"=3)

 

 

Statistics

----------------------------------------------------------

          0  recursive calls

          0  db block gets

          4  consistent gets

          0  physical reads

          0  redo size

        476  bytes sent via SQL*Net to client

        400  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

          1  rows processed

 

SQL>

SQL> select /*+ index_ffs(a)*/owner,data_object_id from t_test_uni_1 a

  2  where wner = 'SYS';

 

23223 rows selected.

 

 

Execution Plan

----------------------------------------------------------

Plan hash value: 3246279645

 

--------------------------------------------------------------------------------

----------------

 

| Id  | Operation            | Name                    | Rows  | Bytes | Cost (%

CPU)| Time     |

 

--------------------------------------------------------------------------------

----------------

 

|   0 | SELECT STATEMENT     |                         |  2394 | 16758 |    33

 (4)| 00:00:01 |

 

|*  1 |  INDEX FAST FULL SCAN| IDX_TEST_UNI_1_OWNER_ID |  2394 | 16758 |    33

 (4)| 00:00:01 |

 

--------------------------------------------------------------------------------

----------------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

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

 

 

Statistics

----------------------------------------------------------

          0  recursive calls

          0  db block gets

       1690  consistent gets

          0  physical reads

          0  redo size

     320570  bytes sent via SQL*Net to client

      17428  bytes received via SQL*Net from client

       1550  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

      23223  rows processed

 

SQL>

SQL> select /*+ index(a)*/owner,data_object_id from t_test_uni_1 a

  2  where wner = 'SYS';

 

23223 rows selected.

 

 

Execution Plan

----------------------------------------------------------

Plan hash value: 295890889

 

--------------------------------------------------------------------------------

------------

 

| Id  | Operation        | Name                    | Rows  | Bytes | Cost (%CPU)

| Time     |

 

--------------------------------------------------------------------------------

------------

 

|   0 | SELECT STATEMENT |                         |  2394 | 16758 |     8   (0)

| 00:00:01 |

 

|*  1 |  INDEX RANGE SCAN| IDX_TEST_UNI_1_OWNER_ID |  2394 | 16758 |     8   (0)

| 00:00:01 |

 

--------------------------------------------------------------------------------

------------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

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

 

 

Statistics

----------------------------------------------------------

          1  recursive calls

          0  db block gets

       1598  consistent gets

          0  physical reads

          0  redo size

     320570  bytes sent via SQL*Net to client

      17428  bytes received via SQL*Net from client

       1550  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

      23223  rows processed

 

SQL>

 

 

6index skip scan

當索引的第一列並沒有出現在where中時,可以通過skip scan的方式來使用組合索引。

SQL> select /*+ index(a IDX_TEST_UNI_1_OWNER_ID)*/count(*) from t_test_uni_1 a

  2  where data_object_id = 2;

 

 

Execution Plan

----------------------------------------------------------

Plan hash value: 475888785

 

--------------------------------------------------------------------------------

------------

 

| Id  | Operation        | Name                    | Rows  | Bytes | Cost (%CPU)

| Time     |

 

--------------------------------------------------------------------------------

------------

 

|   0 | SELECT STATEMENT |                         |     1 |     2 |    24   (0)

| 00:00:01 |

 

|   1 |  SORT AGGREGATE  |                         |     1 |     2 |

|          |

 

|*  2 |   INDEX SKIP SCAN| IDX_TEST_UNI_1_OWNER_ID |     1 |     2 |    24   (0)

| 00:00:01 |

 

--------------------------------------------------------------------------------

------------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   2 - access("DATA_OBJECT_ID"=2)

       filter("DATA_OBJECT_ID"=2)

 

 

Statistics

----------------------------------------------------------

          1  recursive calls

          0  db block gets

         16  consistent gets

          0  physical reads

          0  redo size

        411  bytes sent via SQL*Net to client

        400  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

          1  rows processed

 

SQL>

 

7,bitmap index

bitmap索引建立的合適時,對於一些查詢也是很高效的。

SQL> create bitmap index idx_bitmap_test_uni1 on t_test_uni_1(object_type);

 

Index created.

 

SQL>

SQL> select /*+ */* from t_test_uni_1 a where a.object_type = 'TABLE';

 

2347 rows selected.

 

 

Execution Plan

----------------------------------------------------------

Plan hash value: 1626142262

 

--------------------------------------------------------------------------------

--

 

| Id  | Operation         | Name         | Rows  | Bytes | Cost (%CPU)| Time

 |

 

--------------------------------------------------------------------------------

--

 

|   0 | SELECT STATEMENT  |              |  1376 |   115K|   174   (2)| 00:00:03

 |

 

|*  1 |  TABLE ACCESS FULL| T_TEST_UNI_1 |  1376 |   115K|   174   (2)| 00:00:03

 |

 

--------------------------------------------------------------------------------

--

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   1 - filter("A"."OBJECT_TYPE"='TABLE')

 

 

Statistics

----------------------------------------------------------

          0  recursive calls

          0  db block gets

        913  consistent gets

          0  physical reads

          0  redo size

     119335  bytes sent via SQL*Net to client

       2116  bytes received via SQL*Net from client

        158  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

       2347  rows processed

 

SQL>

 

SQL> select /*+ index(a idx_bitmap_test_uni1)*/* from t_test_uni_1 a where a.object_type = 'TABLE';

 

2347 rows selected.

 

 

Execution Plan

----------------------------------------------------------

Plan hash value: 1471543534

 

--------------------------------------------------------------------------------

---------------------

 

| Id  | Operation                    | Name                 | Rows  | Bytes | Co

st (%CPU)| Time     |

 

--------------------------------------------------------------------------------

---------------------

 

|   0 | SELECT STATEMENT             |                      |  1376 |   115K|

174   (0)| 00:00:03 |

 

|   1 |  TABLE ACCESS BY INDEX ROWID | T_TEST_UNI_1         |  1376 |   115K|

174   (0)| 00:00:03 |

 

|   2 |   BITMAP CONVERSION TO ROWIDS|                      |       |       |

         |          |

 

|*  3 |    BITMAP INDEX SINGLE VALUE | IDX_BITMAP_TEST_UNI1 |       |       |

         |          |

 

--------------------------------------------------------------------------------

---------------------

 

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   3 - access("A"."OBJECT_TYPE"='TABLE')

 

 

Statistics

----------------------------------------------------------

          0  recursive calls

          0  db block gets

        293  consistent gets

          0  physical reads

          0  redo size

     119519  bytes sent via SQL*Net to client

       2116  bytes received via SQL*Net from client

        158  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

       2347  rows processed

 

SQL>

 

 

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16179598/viewspace-668404/,如需轉載,請註明出處,否則將追究法律責任。

相關文章