Oracle 全表掃描及其執(zhí)行計(jì)劃
本文涉及到的相關(guān)鏈接:
Oracle db_file_mulitblock_read_count參數(shù)
1、什么是全表掃描?
全表掃描就是掃表表中所有的行,實(shí)際上是掃描表中所有的數(shù)據(jù)塊,因?yàn)镺racle中最小的存儲(chǔ)單位是Oracle block。
掃描所有的數(shù)據(jù)塊就包括高水位線(xiàn)以?xún)?nèi)的數(shù)據(jù)塊,即使是空數(shù)據(jù)塊在沒(méi)有被釋放的情形下也會(huì)被掃描而導(dǎo)致I/O增加。
在全表掃描期間,通常情況下,表上這些相鄰的數(shù)據(jù)塊被按順序(sequentially)的方式訪問(wèn)以使得一次I/O可以讀取多個(gè)數(shù)據(jù)塊。
一次讀取更多的數(shù)據(jù)塊有助于全表掃描使用更少的I/O,對(duì)于可讀取的數(shù)據(jù)塊被限制于參數(shù)DB_FILE_MULTIBLOCK_READ_COUNT。
2、何時(shí)發(fā)生全表掃描?
a、表上的索引失效或無(wú)法被使用的情形(如對(duì)謂詞使用函數(shù)、計(jì)算、NULL值、不等運(yùn)算符、類(lèi)型轉(zhuǎn)換)
b、查詢(xún)條件返回了整個(gè)表的大部分?jǐn)?shù)據(jù)
c、使用了并行方式訪問(wèn)表
d、使用full 提示
e、統(tǒng)計(jì)信息缺失時(shí)使得Oracle認(rèn)為全表掃描比索引掃描更高效
f、表上的數(shù)據(jù)塊小于DB_FILE_MULTIBLOCK_READ_COUNT值的情形可能產(chǎn)生全表掃描
3、演示全表掃描的情形
a、準(zhǔn)備演示環(huán)境
scott@ORA11G> select * from v$version where rownum<2;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
--創(chuàng)建表t
scott@ORA11G> CREATE TABLE t
2 AS
3 SELECT rownum AS n, rpad('*',100,'*') AS pad
4 FROM dual
5 CONNECT BY level <= 1000;
Table created.
--添加索引
scott@ORA11G> create unique index t_pk on t(n);
Index created.
scott@ORA11G> alter table t add constraint t_pk primary key(n) using index t_pk;
Table altered.
--收集統(tǒng)計(jì)信息
scott@ORA11G> execute dbms_stats.gather_table_stats('SCOTT','T',cascade=>true);
PL/SQL procedure successfully completed.
scott@ORA11G> set autot trace exp;
scott@ORA11G> select count(*) from t; --->count(*)的時(shí)候使用了索引快速掃描
Execution Plan
----------------------------------------------------------
Plan hash value: 454320086
----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FAST FULL SCAN| T_PK | 1000 | 2 (0)| 00:00:01 |
----------------------------------------------------------------------
scott@ORA11G> set autot off;
scott@ORA11G> alter table t move; --->進(jìn)行move table
Table altered.
-->move 之后索引失效,如下所示
scott@ORA11G> @idx_info
Enter value for owner: scott
Enter value for table_name: t
Table Name INDEX_NAME CL_NAM CL_POS STATUS IDX_TYP DSCD
------------- -------------- -------------------- ------ -------- --------------- ----
T T_PK N 1 UNUSABLE NORMAL ASC
b、索引失效導(dǎo)致全表掃描
scott@ORA11G> set autot trace exp;
scott@ORA11G> select count(*) from t;
Execution Plan
----------------------------------------------------------
Plan hash value: 2966233522
-------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 7 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| T | 1000 | 7 (0)| 00:00:01 |
-------------------------------------------------------------------
scott@ORA11G> set autot off;
scott@ORA11G> alter index t_pk rebuild; -->重建索引
Index altered.
scott@ORA11G> @idx_info
Enter value for owner: scott
Enter value for table_name: t
Table Name INDEX_NAME CL_NAM CL_POS STATUS IDX_TYP DSCD
-------------- ---------------- -------------------- ------ -------- --------------- ----
T T_PK N 1 VALID NORMAL ASC
c、返回了整個(gè)表的大部分?jǐn)?shù)據(jù)使用了全表掃描
scott@ORA11G> select count(pad) from t where n<=990;
Execution Plan
----------------------------------------------------------
Plan hash value: 2966233522
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 105 | 7 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 105 | | |
|* 2 | TABLE ACCESS FULL| T | 991 | 101K| 7 (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("N"<=990)
--返回小部分?jǐn)?shù)據(jù)時(shí),使用的是索引掃描
scott@ORA11G> select count(pad) from t where n<=10;
Execution Plan
----------------------------------------------------------
Plan hash value: 4270555908
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 105 | 3 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 105 | | |
| 2 | TABLE ACCESS BY INDEX ROWID| T | 10 | 1050 | 3 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | T_PK | 10 | | 2 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("N"<=10)
d、使用并行方式訪問(wèn)表時(shí)使用了全表掃描
scott@ORA11G> select /*+ parallel(3) */ count(pad) from t where n<=10;
Execution Plan
----------------------------------------------------------
Plan hash value: 3126468333
----------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
----------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 105 | 3 (0)| 00:00:01 | | | |
| 1 | SORT AGGREGATE | | 1 | 105 | | | | | |
| 2 | PX COORDINATOR | | | | | | | | |
| 3 | PX SEND QC (RANDOM) | :TQ10000 | 1 | 105 | | | Q1,00 | P->S | QC (RAND) |
| 4 | SORT AGGREGATE | | 1 | 105 | | | Q1,00 | PCWP | |
| 5 | PX BLOCK ITERATOR | | 10 | 1050 | 3 (0)| 00:00:01 | Q1,00 | PCWC | |
|* 6 | TABLE ACCESS FULL| T | 10 | 1050 | 3 (0)| 00:00:01 | Q1,00 | PCWP | |
----------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
6 - filter("N"<=10)
Note
-----
- Degree of Parallelism is 3 because of hint
--Author : Robinson
--Blog :http://blog.csdn.net/robinson_0612
e、使用full提示時(shí)使用了全表掃描
scott@ORA11G> select /*+ full(t) */ count(pad) from t where n<=10;
Execution Plan
----------------------------------------------------------
Plan hash value: 2966233522
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 105 | 7 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 105 | | |
|* 2 | TABLE ACCESS FULL| T | 10 | 1050 | 7 (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("N"<=10)
f、統(tǒng)計(jì)信息缺失導(dǎo)致全表掃描的情形
scott@ORA11G> exec dbms_stats.delete_table_stats('SCOTT','T');
PL/SQL procedure successfully completed.
scott@ORA11G> select count(pad) from t where n<=10;
Execution Plan
----------------------------------------------------------
Plan hash value: 2966233522
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 65 | 7 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 65 | | |
|* 2 | TABLE ACCESS FULL| T | 10 | 650 | 7 (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("N"<=10)
Note
-----
- dynamic sampling used for this statement (level=2)
--上面的執(zhí)行計(jì)劃使用了全表掃描,而且提示使用了動(dòng)態(tài)采樣,也就是缺乏統(tǒng)計(jì)信息
--表上的數(shù)據(jù)塊小于DB_FILE_MULTIBLOCK_READ_COUNT值的情形可能產(chǎn)生全表掃描的情形不演示
--先來(lái)做幾個(gè)實(shí)驗(yàn) Table Name Index Name CL_NAM CL_POS Status IDX_TYP DSCD scott@ORA11G> @idx_stat AVG LEAF BLKS AVG DATA BLKS --數(shù)據(jù)庫(kù)參數(shù)設(shè)置 NAME TYPE VALUE NAME TYPE VALUE
Execution Plan scott@ORA11G> alter system flush buffer_cache; Execution Plan --注意對(duì)比上面兩次操作中的consistent gets與physical reads
Execution Plan --下面使用提示來(lái)強(qiáng)制優(yōu)化器走索引掃描 Execution Plan |
--使用scott下dept表,僅有4行數(shù)據(jù) 3 rows selected. Execution Plan -->下面強(qiáng)制使用全表掃描 3 rows selected. Execution Plan --下面來(lái)看看count(*)的情形 1 row selected. Execution Plan -->下面強(qiáng)制使用全表掃描 1 row selected. Execution Plan |
posted on 2013-06-07 10:10 順其自然EVO 閱讀(285) 評(píng)論(0) 編輯 收藏 所屬分類(lèi): 數(shù)據(jù)庫(kù)