天天看點

【SQL】查找資料的方式 (一)

sql> set autot on  

sql> select rowid, object_id

  2  from test

  3  where rowid ='aaarvkaaeaaaad8aaa';

rowid               object_id

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

aaarvkaaeaaaad8aaa         28

elapsed: 00:00:00.01

execution plan

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

plan hash value: 2153624467

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

| id  | operation                  | name |

|   0 | select statement           |      |

|   1 |  table access by user rowid| test |

note

-----

   - rule based optimizer used (consider using cbo)

statistics

          1  recursive calls

          0  db block gets

          1  consistent gets

          0  physical reads

          0  sorts (memory)

          0  sorts (disk)

          1  rows processed

注意到統計資訊,隻有一個consistent gets,隻需要一次讀取即可以獲得資料。這種方式是通路資料最快的方式。

----當查詢條件無法命中任何索引或者掃描索引的代價大于全表掃描代價的某一比率(optimizer_index_cost_adj)的時候,oracle會選擇使用全表掃描。此時oracle 會讀取一定數量的資料塊,直到hwm。

sql> select rowid ,object_id

  3  where rownum =1;

elapsed: 00:00:00.00

plan hash value: 2347100821

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

| id  | operation          | name |

|   0 | select statement   |      |

|*  1 |  count stopkey     |      |

|   2 |   table access full| test |--全表掃描。

predicate information (identified by operation id):

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

   1 - filter(rownum=1)

          4  consistent gets

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

sql> select rowid ,object_id from test where rowid = 'aaarvkaaeaaaad8aaa';

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

| id  | operation                  | name | rows  | bytes | cost (%cpu)| time     |

|   0 | select statement           |      |     1 |    17 |     1   (0)| 00:00:01 |

|   1 |  table access by user rowid| test |     1 |    17 |     1   (0)| 00:00:01 |

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

        147  recursive calls

         14  consistent gets

          0  redo size

        。。。

          3  sorts (memory)

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

----建立索引

sql> create table un_test tablespace users as select * from dba_objects;

table created.

elapsed: 00:00:02.18

sql> create unique index i_test_uni on un_test (object_id);

index created.

elapsed: 00:00:00.24

---index unique scan 當索引為unique時,每個子葉節點隻會指向一條資料.

如果oracle預測到隻有0或1條資料時,就會選擇index unique scan .

sql> select object_id from un_test where object_id =28;

 object_id

----------

        28

plan hash value: 333614268

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

| id  | operation         | name       | rows  | bytes | cost (%cpu)| time     |

|   0 | select statement  |            |     1 |     5 |     1   (0)| 00:00:01 |

|*  1 |  index unique scan| i_test_uni |     1 |     5 |     1   (0)| 00:00:01 |

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

   1 - access("object_id"=28)

---index range scan

當通過索引查找資料時,oracle 認為會傳回資料可能大于1 ,會進行index range scan.

例如進行範圍查詢,< , > ,like,between val1 and val2 ,in 等操作。

index range scan, index unique scan 會引起db file sequential read 等待

sql> select object_id from un_test where object_id >5 and object_id <9;

         6

         7

         8

plan hash value: 1694266620

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

| id  | operation        | name       | rows  | bytes | cost (%cpu)| time     |

|   0 | select statement |            |     1 |     5 |     2   (0)| 00:00:01 |

|*  1 |  index range scan| i_test_uni |     1 |     5 |     2   (0)| 00:00:01 |

   1 - access("object_id">5 and "object_id"<9)

--index fast full scan

  索引快速掃描和全表掃描類似,一次讀取db_file_multiblock_count 個資料塊。index fast full scan

與其他索引掃描不同,它不會從根節點開始,也不讀取節點,而是直接掃描所有子葉節點;也不會一次讀取一個資料塊。

sql> select object_id from un_test where object_id >3;

53362 rows selected.

elapsed: 00:00:00.25

plan hash value: 972078537

| id  | operation            | name       | rows  | bytes | cost (%cpu)| time     |

|   0 | select statement     |            | 53364 |   260k|    27   (4)| 00:00:01 |

|*  1 |  index fast full scan| i_test_uni | 53364 |   260k|    27   (4)| 00:00:01 |

   1 - filter("object_id">3)

       3670  consistent gets

           。。。。。。。

      53362  rows processed

sql> select object_id from un_test where object_id>500;

52887 rows selected.

|   0 | select statement     |            | 52998 |   258k|    27   (4)| 00:00:01 |

|*  1 |  index fast full scan| i_test_uni | 52998 |   258k|    27   (4)| 00:00:01 |

   1 - filter("object_id">500

       3634  consistent gets

          。。。。。。。。。

      52887  rows processed

有時如果 的值過小,強制使用索引掃描時,會發生index full scan .index full scan 和 index fast full scan 不同。它是一種索引掃描,從根節點開始掃描,周遊整棵索引樹,并且一次讀取一個索引塊,ifs 會引起 db file sequential  read  事件。