Oracle支持SELECT语句只扫描表的一部分记录。

这篇简单介绍SAMPLE扫描和HINT的关系。


Oracle的文档上描述,当不包含SAMPLE语句的时候,可以使用HINT来指定执行计划,实际上即使包含SAMPLE语句,HINT也是生效的。

SQL> SELECT OBJECT_ID FROM T SAMPLE (1) WHERE WNER = USER;

OBJECT_ID

----------

    60607

    70958


执行计划

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

Plan hash value: 3630032853

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

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

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

|   0 | SELECT STATEMENT            |             |    22 |   506 |     6   (0)| 00:00:01 |

|   1 |  TABLE ACCESS BY INDEX ROWID| T           |    22 |   506 |     6   (0)| 00:00:01 |

|*  2 |   INDEX RANGE SCAN          | IND_T_OWNER |    22 |       |     5   (0)| 00:00:01 |

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

Predicate Information (identified by operation id):

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

  2 - access("OWNER"=USER@!)

      filter(ORA_HASH(ROWID,0,2211694651,'SYS_SAMPLE',0)<42949673)


统计信息

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

         0  recursive calls

         0  db block gets

         6  consistent gets

         4  physical reads

         0  redo size

       452  bytes sent via SQL*Net to client

       385  bytes received via SQL*Net from client

         2  SQL*Net roundtrips to/from client

         0  sorts (memory)

         0  sorts (disk)

         2  rows processed

SQL> SELECT /*+ FULL(T) */ OBJECT_ID FROM T SAMPLE (1) WHERE WNER = USER;

未选定行


执行计划

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

Plan hash value: 2767392432

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

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

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

|   0 | SELECT STATEMENT    |      |    22 |   506 |   158   (2)| 00:00:02 |

|*  1 |  TABLE ACCESS SAMPLE| T    |    22 |   506 |   158   (2)| 00:00:02 |

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

Predicate Information (identified by operation id):

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

  1 - filter("OWNER"=USER@!)


统计信息

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

         1  recursive calls

         0  db block gets

       517  consistent gets

       430  physical reads

         0  redo size

       275  bytes sent via SQL*Net to client

       374  bytes received via SQL*Net from client

         1  SQL*Net roundtrips to/from client

         0  sorts (memory)

         0  sorts (disk)

         0  rows processed

Oracle文档还提到基于BLOCK的SAMPLE扫描,只对全表扫描和快速索引全扫有效,而其他执行计划无效,不过索引扫描提供了一种类似实现方式:SYS_SAMPLE_BLOCK

SQL> SELECT OBJECT_ID FROM T SAMPLE BLOCK (1);

未选定行


执行计划

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

Plan hash value: 2767392432

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

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

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

|   0 | SELECT STATEMENT    |      |   496 |  8432 |     3   (0)| 00:00:01 |

|   1 |  TABLE ACCESS SAMPLE| T    |   496 |  8432 |     3   (0)| 00:00:01 |

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


统计信息

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

       219  recursive calls

         0  db block gets

        40  consistent gets

         0  physical reads

         0  redo size

       275  bytes sent via SQL*Net to client

       374  bytes received via SQL*Net from client

         1  SQL*Net roundtrips to/from client

         5  sorts (memory)

         0  sorts (disk)

         0  rows processed

SQL> SELECT OBJECT_ID FROM T SAMPLE BLOCK (1) WHERE OBJECT_ID IS NOT NULL;

未选定行


执行计划

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

Plan hash value: 1022620004

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

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

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

|   0 | SELECT STATEMENT            |          |   496 |  8432 |     2   (0)| 00:00:01 |

|*  1 |  INDEX SAMPLE FAST FULL SCAN| IND_T_ID |   496 |  8432 |     2   (0)| 00:00:01 |

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

Predicate Information (identified by operation id):

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

  1 - filter("OBJECT_ID" IS NOT NULL)


统计信息

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

         1  recursive calls

         0  db block gets

         6  consistent gets

         0  physical reads

         0  redo size

       275  bytes sent via SQL*Net to client

       374  bytes received via SQL*Net from client

         1  SQL*Net roundtrips to/from client

         0  sorts (memory)

         0  sorts (disk)

         0  rows processed

SQL> SELECT /*+ INDEX(T) */ OBJECT_ID FROM T SAMPLE BLOCK (0.01) WHERE OBJECT_ID IS NOT NULL;

OBJECT_ID

----------

      627

    35358

    44369


执行计划

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

Plan hash value: 1376157901

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

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

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

|   0 | SELECT STATEMENT |          |     5 |    85 |   113   (2)| 00:00:02 |

|*  1 |  INDEX FULL SCAN | IND_T_ID |     5 |    85 |   113   (2)| 00:00:02 |

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

Predicate Information (identified by operation id):

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

  1 - filter("OBJECT_ID" IS NOT NULL AND

             ORA_HASH(ROWID,0,533460469,'SYS_SAMPLE_BLOCK',0)<429497)


统计信息

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

         1  recursive calls

         0  db block gets

       112  consistent gets

         0  physical reads

         0  redo size

       461  bytes sent via SQL*Net to client

       385  bytes received via SQL*Net from client

         2  SQL*Net roundtrips to/from client

         0  sorts (memory)

         0  sorts (disk)

         3  rows processed

事实上SAMPLE和HINT二者并不矛盾,绝大部分情况下,Oracle采用的执行计划会同时满足二者的需求。


oracle视频教程请关注:http://u.youku.com/user_video/id_UMzAzMjkxMjE2.html