ORACLE 执行计划分析
?http://www.cnblogs.com/rootq/archive/2008/09/06/1285779.html
?
ORACLE 執(zhí)行計劃分析
一、什么是執(zhí)行計劃An explain plan is a representation of the access path that is taken when a query is executed within Oracle.
二、如何訪問數(shù)據(jù)
At the physical level Oracle reads blocks of data. The smallest amount of data read is a single Oracle block, the largest is constrained by operating system limits (and multiblock i/o). Logically Oracle finds the data to read by using the following methods:
Full Table Scan (FTS)??? --全表掃描
Index Lookup (unique & non-unique)??? --索引掃描(唯一和非唯一)
Rowid??? --物理行id
三、執(zhí)行計劃層次關(guān)系
When looking at a plan, the rightmost (ie most inndented) uppermost operation is the first thing that is executed. --采用最右最上最先執(zhí)行的原則看層次關(guān)系,在同一級如果某個動作沒有子ID就最先執(zhí)行
1.看一個簡單的例子:
Query Plan
-----------------------------------------
SELECT STATEMENT [CHOOSE] Cost=1234
**TABLE ACCESS FULL LARGE [:Q65001] [ANALYZED] --[:Q65001]表示是并行方式,[ANALYZED]表示該對象已經(jīng)分析過了
優(yōu)化模式是CHOOSE的情況下,看Cost參數(shù)是否有值來決定采用CBO還是RBO:
SELECT STATEMENT [CHOOSE] Cost=1234 --Cost有值,采用CBO
SELECT STATEMENT [CHOOSE] Cost= --Cost為空,采用RBO
?
2.層次的父子關(guān)系,看比較復(fù)雜的例子:
PARENT1
**FIRST CHILD
****FIRST GRANDCHILD
**SECOND CHILD
Here the same principles apply, the FIRST GRANDCHILD is the initial operation then the FIRST CHILD followed by the SECOND CHILD and finally the PARENT collates the output.
四、例子解說
Execution Plan
----------------------------------------------------------
0 **SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=8 Bytes=248)
1 0 **HASH JOIN (Cost=3 Card=8 Bytes=248)
2 1 ****TABLE ACCESS (FULL) OF 'DEPT' (Cost=1 Card=3 Bytes=36)
3 1 ****TABLE ACCESS (FULL) OF 'EMP' (Cost=1 Card=16 Bytes=304)
左側(cè)的兩排數(shù)據(jù),前面的是序列號ID,后面的是對應(yīng)的PID(父ID)。
A shortened summary of this is:
Execution starts with ID=0: SELECT STATEMENT but this is dependand on it's child objects
So it executes its first child step: ID=1 PID=0 HASH JOIN but this is dependand on it's child objects
So it executes its first child step: ID=2 PID=1 TABLE ACCESS (FULL) OF 'DEPT'
Then the second child step: ID=3 PID=2 TABLE ACCESS (FULL) OF 'EMP'
Rows are returned to the parent step(s) until finished
五、表訪問方式
1.Full Table Scan (FTS) 全表掃描
In a FTS operation, the whole table is read up to the high water mark (HWM). The HWM marks the last block in the table that has ever had data written to it. If you have deleted all the rows then you will still read up to the HWM. Truncate resets the HWM back to the start of the table. FTS uses multiblock i/o to read the blocks from disk.?? --全表掃描模式下會讀數(shù)據(jù)到表的高水位線(HWM即表示表曾經(jīng)擴展的最后一個數(shù)據(jù)塊),讀取速度依賴于Oracle初始化參數(shù)db_block_multiblock_read_count
Query Plan
------------------------------------
SELECT STATEMENT [CHOOSE] Cost=1
**INDEX UNIQUE SCAN EMP_I1?? --如果索引里就找到了所要的數(shù)據(jù),就不會再去訪問表了
There are 5 methods of index lookup:
index unique scan?? --索引唯一掃描
Method for looking up a single key value via a unique index. always returns a single value, You must supply AT LEAST the leading column of the index to access data via the index.
eg:
SQL> explain plan for select empno,ename from emp where empno=10;
index range scan?? --索引局部掃描
Index range scan is a method for accessing a range values of a particular column. AT LEAST the leading column of the index must be supplied to access data via the index. Can be used for range operations (e.g. > < <> >= <= between) .
eg:
SQL> explain plan for select mgr from emp where mgr = 5;
index full scan?? --索引全局掃描
Full index scans are only available in the CBO as otherwise we are unable to determine whether a full scan would be a good idea or not. We choose an index Full Scan when we have statistics that indicate that it is going to be more efficient than a Full table scan and a sort. For example we may do a Full index scan when we do an unbounded scan of an index and want the data to be ordered in the index order.
eg:
SQL> explain plan for select empno,ename from big_emp order by empno,ename;
index fast full scan?? --索引快速全局掃描,不帶order by情況下常發(fā)生
Scans all the block in the index, Rows are not returned in sorted order, Introduced in 7.3 and requires V733_PLANS_ENABLED=TRUE and CBO, may be hinted using INDEX_FFS hint, uses multiblock i/o, can be executed in parallel, can be used to access second column of concatenated indexes. This is because we are selecting all of the index.
eg:
SQL> explain plan for select empno,ename from big_emp;
index skip scan?? --索引跳躍掃描,where條件列是非索引的前導(dǎo)列情況下常發(fā)生
Index skip scan finds rows even if the column is not the leading column of a concatenated index. It skips the first column(s) during the search.
eg:
SQL> create index i_emp on emp(empno, ename);
SQL> select /*+ index_ss(emp i_emp)*/ job from emp where ename='SMITH';
3.Rowid 物理ID掃描
This is the quickest access method available.Oracle retrieves the specified block and extracts the rows it is interested in. --Rowid掃描是最快的訪問數(shù)據(jù)方式
六、表連接方式
有三種連接方式:
1.Sort Merge Join (SMJ) ?? --由于sort是非常耗資源的,所以這種連接方式要避免
Rows are produced by Row Source 1 and are then sorted Rows from Row Source 2 are then produced and sorted by the same sort key as Row Source 1. Row Source 1 and 2 are NOT accessed concurrently.
SQL> explain plan for
select /*+ ordered */ e.deptno,d.deptno
from emp e,dept d
where e.deptno = d.deptno
order by e.deptno,d.deptno;
Query Plan
-------------------------------------
SELECT STATEMENT [CHOOSE] Cost=17
**MERGE JOIN
****SORT JOIN
******TABLE ACCESS FULL EMP [ANALYZED]
****SORT JOIN
******TABLE ACCESS FULL DEPT [ANALYZED]
?
Sorting is an expensive operation, especially with large tables. Because of this, SMJ is often not a particularly efficient join method.
2.Nested Loops (NL) ?? --比較高效的一種連接方式
Fetches the first batch of rows from row source 1, Then we probe row source 2 once for each row returned from row source 1.
For nested loops to be efficient it is important that the first row source returns as few rows as possible as this directly controls the number of probes of the second row source. Also it helps if the access method for row source 2 is efficient as this operation is being repeated once for every row returned by row source 1.
SQL> explain plan for
select a.dname,b.sql
from dept a,emp b
where a.deptno = b.deptno;
?
Query Plan
-------------------------
SELECT STATEMENT [CHOOSE] Cost=5
**NESTED LOOPS
****TABLE ACCESS FULL DEPT [ANALYZED]
****TABLE ACCESS FULL EMP [ANALYZED]
3.Hash Join ?? --最為高效的一種連接方式
New join type introduced in 7.3, More efficient in theory than NL & SMJ, Only accessible via the CBO. Smallest row source is chosen and used to build a hash table and a bitmap The second row source is hashed and checked against the hash table looking for joins. The bitmap is used as a quick lookup to check if rows are in the hash table and are especially useful when the hash table is too large to fit in memory.
?
SQL> explain plan for
select /*+ use_hash(emp) */ empno
from emp,dept
where emp.deptno = dept.deptno;
?
Query Plan
----------------------------
SELECT STATEMENT [CHOOSE] Cost=3
**HASH JOIN
****TABLE ACCESS FULL DEPT
****TABLE ACCESS FULL EMP
?
Hash joins are enabled by the parameter HASH_JOIN_ENABLED=TRUE in the init.ora or session. TRUE is the default in 7.3.
3.Cartesian Product ?? --卡迪爾積,不算真正的連接方式,sql肯定寫的有問題
A Cartesian Product is done where they are no join conditions between 2 row sources and there is no alternative method of accessing the data. Not really a join as such as there is no join! Typically this is caused by a coding mistake where a join has been left out.
It can be useful in some circumstances - Star joins uses cartesian products.Notice that there is no join between the 2 tables:
?
SQL> explain plan for
select emp.deptno,dept,deptno
from emp,dept
?
Query Plan
------------------------------
SLECT STATEMENT [CHOOSE] Cost=5
**MERGE JOIN CARTESIAN
****TABLE ACCESS FULL DEPT
****SORT JOIN
******TABLE ACCESS FULL EMP
?
The CARTESIAN keyword indicate that we are doing a cartesian product.
七、運算符
1.sort ?? --排序,很消耗資源
There are a number of different operations that promote sorts:
order by clauses
group by
sort merge join
2.filter ?? --過濾,如not in、min函數(shù)等容易產(chǎn)生
Has a number of different meanings, used to indicate partition elimination, may also indicate an actual filter step where one row source is filtering, another, functions such as min may introduce filter steps into query plans.
3.view ?? --視圖,大都由內(nèi)聯(lián)視圖產(chǎn)生
When a view cannot be merged into the main query you will often see a projection view operation. This indicates that the 'view' will be selected from directly as opposed to being broken down into joins on the base tables. A number of constructs make a view non mergeable. Inline views are also non mergeable.
eg:
SQL> explain plan for
select ename,tot
from emp,(select empno,sum(empno) tot from big_emp group by empno) tmp
where emp.empno = tmp.empno;
?
Query Plan
------------------------
SELECT STATEMENT [CHOOSE]
**HASH JOIN
**TABLE ACCESS FULL EMP [ANALYZED]
**VIEW
****SORT GROUP BY
******INDEX FULL SCAN BE_IX
4.partition view ??? --分區(qū)視圖
?
Partition views are a legacy technology that were superceded by the partitioning option. This section of the article is provided as reference for such legacy systems.
http://blog.csdn.net/tianlesoftware/article/details/5827245 如果要分析某條SQL的性能問題,通常我們要先看SQL的執(zhí)行計劃,看看SQL的每一步執(zhí)行是否存在問題。 如果一條SQL平時執(zhí)行的好好的,卻有一天突然性能很差,如果排除了系統(tǒng)資源和阻塞的原因,那么基本可以斷定是執(zhí)行計劃出了問題。??????
?????? 看懂執(zhí)行計劃也就成了SQL優(yōu)化的先決條件。 這里的SQL優(yōu)化指的是SQL性能問題的定位,定位后就可以解決問題。
?
?
一.???????? 查看執(zhí)行計劃的三種方法
1.1 設(shè)置autotrace
| 序號 | 命令 | 解釋 |
| 1 | SET?AUTOTRACE?OFF | 此為默認(rèn)值,即關(guān)閉Autotrace? |
| 2 | SET?AUTOTRACE?ON?EXPLAIN | 只顯示執(zhí)行計劃 |
| 3 | SET?AUTOTRACE?ON?STATISTICS | ?只顯示執(zhí)行的統(tǒng)計信息 |
| 4 | SET?AUTOTRACE?ON | ?包含2,3兩項內(nèi)容 |
| 5 | SET?AUTOTRACE?TRACEONLY | ?與ON相似,但不顯示語句的執(zhí)行結(jié)果 |
?
SQL> set autotrace on
SQL> select * from dave;
??????? ID NAME
---------- ----------
???????? 8 安慶
? ???????1 dave
???????? 2 bl
???????? 1 bl
???????? 2 dave
???????? 3 dba
???????? 4 sf-express
???????? 5 dmm
?
已選擇8行。
?
執(zhí)行計劃
----------------------------------------------------------
Plan hash value: 3458767806
--------------------------------------------------------------------------
| Id? | Operation???????? | Name | Rows? | Bytes | Cost (%CPU)| Time???? |
--------------------------------------------------------------------------
|?? 0 | SELECT STATEMENT? |????? |???? 8 |??? 64 |???? 2?? (0)| 00:00:01 |
|?? 1 |? TABLE ACCESS FULL| DAVE |???? 8 |??? 64 |???? 2?? (0)| 00:00:01 |
--------------------------------------------------------------------------
?
統(tǒng)計信息
----------------------------------------------------------
????????? 0? recursive calls
????????? 0? db block gets
????????? 4? consistent gets
????????? 0? physical reads
????????? 0? redo size
??????? 609? bytes sent via SQL*Net to client
??????? 416? bytes received via SQL*Net from client
????????? 2? SQL*Net roundtrips to/from client
????????? 0? sorts (memory)
????????? 0? sorts (disk)
????????? 8? rows processed
?
SQL>
?
1.2 使用SQL
SQL>EXPLAIN PLAN FOR sql語句;
SQL>SELECT plan_table_output FROM TABLE(DBMS_XPLAN.DISPLAY('PLAN_TABLE'));
?
示例:
SQL> EXPLAIN PLAN FOR SELECT * FROM DAVE;
已解釋。
SQL> SELECT plan_table_output FROM TABLE(DBMS_XPLAN.DISPLAY('PLAN_TABLE'));
或者:
SQL>? select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 3458767806
?
--------------------------------------------------------------------------
| Id? | Operation???????? | Name | Rows? | Bytes | Cost (%CPU)| Time???? |
--------------------------------------------------------------------------
|?? 0 | SELECT STATEMENT? |????? |???? 8 |??? 64 |???? 2?? (0)| 00:00:01 |
|?? 1 |? TABLE ACCESS FULL| DAVE |???? 8 |??? 64 |???? 2?? (0)| 00:00:01 |
--------------------------------------------------------------------------
已選擇8行。
執(zhí)行計劃
----------------------------------------------------------
Plan hash value: 2137789089
--------------------------------------------------------------------------------
| Id? | Operation???????????????????????? | Name??? | Rows? | Bytes | Cost (%CPU)| Time???? |
---------------------------------------------------------------------------------------------
|?? 0 | SELECT STATEMENT????????????????? |???????? |? 8168 | 16336 |??? 29?? (0)| 00:00:01 |
|?? 1 |? COLLECTION ITERATOR PICKLER FETCH| DISPLAY |? 8168 | 16336 |??? 29?? (0)| 00:00:01 |
---------------------------------------------------------------------------------------------
?
統(tǒng)計信息
----------------------------------------------------------
???????? 25? recursive calls
???????? 12? db block gets
??????? 168? consistent gets
????????? 0? physical reads
????????? 0? redo size
??????? 974? bytes sent via SQL*Net to client
??????? 416? bytes received via SQL*Net from client
????????? 2? SQL*Net roundtrips to/from client
????????? 1? sorts (memory)
????????? 0? sorts (disk)
????????? 8? rows processed
SQL>
?
1.3 使用Toad,PL/SQL Developer工具
?
?
二.???????? Cardinality(基數(shù))/ rows
Cardinality值表示CBO預(yù)期從一個行源(row source)返回的記錄數(shù),這個行源可能是一個表,一個索引,也可能是一個子查詢。 ? 在Oracle 9i中的執(zhí)行計劃中,Cardinality縮寫成Card。 在10g中,Card值被rows替換。
?
這是9i的一個執(zhí)行計劃,我們可以看到關(guān)鍵字Card:
?????? 執(zhí)行計劃
----------------------------------------------------------
?? 0????? SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=402)
?? 1??? 0?? TABLE ACCESS (FULL) OF 'TBILLLOG8' (Cost=2 Card=1 Bytes=402)
?
Oracle 10g的執(zhí)行計劃,關(guān)鍵字換成了rows:
執(zhí)行計劃
----------------------------------------------------------
Plan hash value: 2137789089
--------------------------------------------------------------------------------
| Id? | Operation???????????????????????? | Name??? | Rows ?| Bytes | Cost (%CPU)| Time???? |
---------------------------------------------------------------------------------------------
|?? 0 | SELECT STATEMENT???????????? ?????|???????? |? 8168 | 16336 |??? 29?? (0)| 00:00:01 |
|?? 1 |? COLLECTION ITERATOR PICKLER FETCH| DISPLAY |? 8168 | 16336 |??? 29?? (0)| 00:00:01 |
---------------------------------------------------------------------------------------------
?
Cardinality的值對于CBO做出正確的執(zhí)行計劃來說至關(guān)重要。 如果CBO獲得的Cardinality值不夠準(zhǔn)確(通常是沒有做分析或者分析數(shù)據(jù)過舊造成),在執(zhí)行計劃成本計算上就會出現(xiàn)偏差,從而導(dǎo)致CBO錯誤的制定出執(zhí)行計劃。
?
?????? 在多表關(guān)聯(lián)查詢或者SQL中有子查詢時,每個關(guān)聯(lián)表或子查詢的Cardinality的值對主查詢的影響都非常大,甚至可以說,CBO就是依賴于各個關(guān)聯(lián)表或者子查詢Cardinality值計算出最后的執(zhí)行計劃。
?
?????? 對于多表查詢,CBO使用每個關(guān)聯(lián)表返回的行數(shù)(Cardinality)決定用什么樣的訪問方式來做表關(guān)聯(lián)(如Nested loops Join 或 hash Join)。
???? ???? 多表連接的三種方式詳解 HASH JOIN MERGE JOIN NESTED LOOP
????????????? http://blog.csdn.net/tianlesoftware/archive/2010/08/20/5826546.aspx
?
對于子查詢,它的Cardinality將決定子查詢是使用索引還是使用全表掃描的方式訪問數(shù)據(jù)。
?
?
?
三. SQL 的執(zhí)行計劃
?????? 生成SQL的執(zhí)行計劃是Oracle在對SQL做硬解析時的一個非常重要的步驟,它制定出一個方案告訴Oracle在執(zhí)行這條SQL時以什么樣的方式訪問數(shù)據(jù):索引還是全表掃描,是Hash Join還是Nested loops Join等。 比如說某條SQL通過使用索引的方式訪問數(shù)據(jù)是最節(jié)省資源的,結(jié)果CBO作出的執(zhí)行計劃是全表掃描,那么這條SQL的性能必然是比較差的。
?????? Oracle SQL的硬解析和軟解析
?????? http://blog.csdn.net/tianlesoftware/archive/2010/04/08/5458896.aspx
?
示例:
SQL> SET AUTOTRACE TRACEONLY;? -- 只顯示執(zhí)行計劃,不顯示結(jié)果集
SQL> select * from scott.emp a,scott.emp b where a.empno=b.mgr;
已選擇13行。
?
執(zhí)行計劃
----------------------------------------------------------
Plan hash value: 992080948
---------------------------------------------------------------------------------------
| Id? | Operation??????????????????? | Name?? | Rows? | Bytes | Cost (%CPU)| Time???? |
---------------------------------------------------------------------------------------
|?? 0 | SELECT STATEMENT???????????? |??????? |??? 13 |?? 988 |???? 6? (17)| 00:00:01 |
|?? 1 |? MERGE JOIN????????????????? |????? ??|??? 13 |?? 988 |???? 6? (17)| 00:00:01 |
|?? 2 |?? TABLE ACCESS BY INDEX ROWID| EMP??? |??? 14 |?? 532 |???? 2?? (0)| 00:00:01 |
|?? 3 |??? INDEX FULL SCAN?????????? | PK_EMP |??? 14 |?????? |???? 1?? (0)| 00:00:01 |
|*? 4 |?? SORT JOIN???????????????? ?|??????? |??? 13 |?? 494 |???? 4? (25)| 00:00:01 |
|*? 5 |??? TABLE ACCESS FULL???????? | EMP??? |??? 13 |?? 494 |???? 3?? (0)| 00:00:01 |
---------------------------------------------------------------------------------------
?
Predicate Information (identified by operation id):
---------------------------------------------------
?? 4 - access("A"."EMPNO"="B"."MGR")
?????? filter("A"."EMPNO"="B"."MGR")
?? 5 - filter("B"."MGR" IS NOT NULL)
?
統(tǒng)計信息
----------------------------------------------------------
????????? 0? recursive calls
????????? 0? db block gets
???????? 11? consistent gets
????????? 0? physical reads
????????? 0? redo size
?????? 2091? bytes sent via SQL*Net to client
??????? 416? bytes received via SQL*Net from client
????????? 2? SQL*Net roundtrips to/from client
????????? 1? sorts (memory)
????????? 0? sorts (disk)
???????? 13? rows processed
SQL>
?
?
?
?
圖片是Toad工具查看的執(zhí)行計劃。 在Toad 里面,很清楚的顯示了執(zhí)行的順序。 但是如果在SQLPLUS里面就不是那么直接。 但我們也可以判斷:一般按縮進(jìn)長度來判斷,縮進(jìn)最大的最先執(zhí)行,如果有2行縮進(jìn)一樣,那么就先執(zhí)行上面的。
?
?
3.1 執(zhí)行計劃中字段解釋:
?????? ID: 一個序號,但不是執(zhí)行的先后順序。執(zhí)行的先后根據(jù)縮進(jìn)來判斷。
?????? Operation: 當(dāng)前操作的內(nèi)容。
?????? Rows: 當(dāng)前操作的Cardinality,Oracle估計當(dāng)前操作的返回結(jié)果集。
?????? Cost(CPU):Oracle 計算出來的一個數(shù)值(代價),用于說明SQL執(zhí)行的代價。
?????? Time:Oracle 估計當(dāng)前操作的時間。
?
3.2 謂詞說明:
Predicate Information (identified by operation id):
---------------------------------------------------
?? 4 - access("A"."EMPNO"="B"."MGR")
?????? filter("A"."EMPNO"="B"."MGR")
?? 5 - filter("B"."MGR" IS NOT NULL)
?
?????? Access: 表示這個謂詞條件的值將會影響數(shù)據(jù)的訪問路勁(表還是索引)。
?????? Filter:表示謂詞條件的值不會影響數(shù)據(jù)的訪問路勁,只起過濾的作用。
?
在謂詞中主要注意access,要考慮謂詞的條件,使用的訪問路徑是否正確。
?
?
3.3 統(tǒng)計信息說明:
?
?
db?block?gets?: 從buffer?cache中讀取的block的數(shù)量? ??
consistent?gets:?從buffer?cache中讀取的undo數(shù)據(jù)的block的數(shù)量? ??
physical?reads:?從磁盤讀取的block的數(shù)量? ??
redo?size:?DML生成的redo的大小? ??
sorts?(memory)?:在內(nèi)存執(zhí)行的排序量? ??
sorts?(disk)?:在磁盤上執(zhí)行的排序量? ??
?
?????? Physical Reads通常是我們最關(guān)心的,如果這個值很高,說明要從磁盤請求大量的數(shù)據(jù)到Buffer Cache里,通常意味著系統(tǒng)里存在大量全表掃描的SQL語句,這會影響到數(shù)據(jù)庫的性能,因此盡量避免語句做全表掃描,對于全表掃描的SQL語句,建議增 加相關(guān)的索引,優(yōu)化SQL語句來解決。
?
關(guān)于physical reads ,db block gets 和consistent gets這三個參數(shù)之間有一個換算公式:
?????? 數(shù)據(jù)緩沖區(qū)的使用命中率=1 - ( physical reads / (db block gets + consistent gets) )。
?
用以下語句可以查看數(shù)據(jù)緩沖區(qū)的命中率:
?????? SQL>SELECT name, value FROM v$sysstat WHERE name IN ('db block gets', 'consistent gets','physical reads');
?????? 查詢出來的結(jié)果Buffer Cache的命中率應(yīng)該在90%以上,否則需要增加數(shù)據(jù)緩沖區(qū)的大小。
?
Recursive Calls: ?Number of recursive calls generated at both the user and system level.????
Oracle Database maintains tables used for internal processing. When it needs to change these tables, Oracle Database generates an internal SQL statement, which in turn generates a recursive call. In short, recursive calls are basically SQL performed on behalf of your SQL. So, if you had to parse the query, for example, you might have had to run some other queries to get data dictionary information. These would be recursive calls. Space management, security checks, calling PL/SQL from SQL—all incur recursive SQL calls。
?
DB Block Gets: Number of times a CURRENT block was requested.
Current mode blocks are retrieved as they exist right now, not in a consistent read fashion. Normally, blocks retrieved for a query are retrieved as they existed when the query began. Current mode blocks are retrieved as they exist right now, not from a previous point in time. During a SELECT, you might see current mode retrievals due to reading the data dictionary to find the extent information for a table to do a full scan (because you need the "right now" information, not the consistent read). During a modification, you will access the blocks in current mode in order to write to them. (DB Block Gets:請求的數(shù)據(jù)塊在buffer能滿足的個數(shù))
?????? 當(dāng)前模式塊意思就是在操作中正好提取的塊數(shù)目,而不是在一致性讀的情況下而產(chǎn)生的塊數(shù)。正常的情況下,一個查詢提取的塊是在查詢開始的那個時間點上存在的數(shù)據(jù)塊,當(dāng)前塊是在這個時刻存在的數(shù)據(jù)塊,而不是在這個時間點之前或者之后的數(shù)據(jù)塊數(shù)目。
?
Consistent Gets: Number of times a consistent read was requested for a block.
This is how many blocks you processed in "consistent read" mode. This will include counts of blocks read from the rollback segment in order to roll back a block. This is the mode you read blocks in with a SELECT, for example. Also, when you do a searched UPDATE/DELETE, you read the blocks in consistent read mode and then get the block in current mode to actually do the modification. (Consistent Gets: 數(shù)據(jù)請求總數(shù)在回滾段Buffer中的數(shù)據(jù)一致性讀所需要的數(shù)據(jù)塊)
?????? 這里的概念是在處理你這個操作的時候需要在一致性讀狀態(tài)上處理多少個塊,這些塊產(chǎn)生的主要原因是因為由于在你查詢的過程中,由于其他會話對數(shù)據(jù)塊進(jìn)行操 作,而對所要查詢的塊有了修改,但是由于我們的查詢是在這些修改之前調(diào)用的,所以需要對回滾段中的數(shù)據(jù)塊的前映像進(jìn)行查詢,以保證數(shù)據(jù)的一致性。這樣就產(chǎn) 生了一致性讀。
?
Physical Reads: Total number of data blocks read from disk. This number equals the value of "physical reads direct" plus all reads into buffer cache. (Physical Reads:實例啟動后,從磁盤讀到Buffer Cache數(shù)據(jù)塊數(shù)量)
就是從磁盤上讀取數(shù)據(jù)塊的數(shù)量,其產(chǎn)生的主要原因是:
?????? (1) 在數(shù)據(jù)庫高速緩存中不存在這些塊
?????? (2) 全表掃描
?????? (3) 磁盤排序
它們?nèi)咧g的關(guān)系大致可概括為:
?????? 邏輯讀指的是Oracle從內(nèi)存讀到的數(shù)據(jù)塊數(shù)量。一般來說是'consistent gets' + 'db block gets'。當(dāng)在內(nèi)存中找不到所需的數(shù)據(jù)塊的話就需要從磁盤中獲取,于是就產(chǎn)生了'physical reads'。
?
Sorts(disk):
??? Number of sort operations that required at least one disk write. Sorts that require I/O to disk are quite resource intensive. Try increasing the size of the initialization parameter SORT_AREA_SIZE.
bytes sent via SQL*Net to client:
??? Total number of bytes sent to the client from the foreground processes.
bytes received via SQL*Net from client:
??? Total number of bytes received from the client over Oracle Net.
SQL*Net roundtrips to/from client:
??? Total number of Oracle Net messages sent to and received from the client.
?
?
更多內(nèi)容參考Oracle聯(lián)機文檔:
?????? Statistics Descriptions
?????? http://download.oracle.com/docs/cd/E11882_01/server.112/e10820/stats002.htm#i375475
?
?
3.4 動態(tài)分析
?????? 如果在執(zhí)行計劃中有如下提示:
????????????? Note
????????????? ------------
???????????????????? -dynamic sampling used for the statement
??????
?????? 這提示用戶CBO當(dāng)前使用的技術(shù),需要用戶在分析計劃時考慮到這些因素。 當(dāng)出現(xiàn)這個提示,說明當(dāng)前表使用了動態(tài)采樣。 我們從而推斷這個表可能沒有做過分析。
?
?
這里會出現(xiàn)兩種情況:
(1)?????? 如果表沒有做過分析,那么CBO可以通過動態(tài)采樣的方式來獲取分析數(shù)據(jù),也可以或者正確的執(zhí)行計劃。
(2)?????? 如果表分析過,但是分析信息過舊,這時CBO就不會在使用動態(tài)采樣,而是使用這些舊的分析數(shù)據(jù),從而可能導(dǎo)致錯誤的執(zhí)行計劃。
?
?
?
總結(jié):
?????? 在看執(zhí)行計劃的時候,除了看執(zhí)行計劃本身,還需要看謂詞和提示信息。 通過整體信息來判斷SQL 效率。
?
?
?
?
?
?
?
整理自網(wǎng)絡(luò)
------------------------------------------------------------------------------
Blog: http://blog.csdn.net/tianlesoftware
網(wǎng)上資源: http://tianlesoftware.download.csdn.net
相關(guān)視頻:http://blog.csdn.net/tianlesoftware/archive/2009/11/27/4886500.aspx
DBA1 群:62697716(滿); DBA2 群:62697977(滿)
DBA3 群:63306533;???? 聊天 群:40132017
總結(jié)
以上是生活随笔為你收集整理的ORACLE 执行计划分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle 函数索引
- 下一篇: oracle查询中表的连接顺序 手工指定