SQL腳本存在TABLE ACCESS FULL行為及其優化



SQL腳本存在TABLE ACCESS FULL行為


對於SQL的執行計划,一般盡量避免TABLE ACCESS FULL的出現,那怎樣去定位,系統里面哪些SQL腳本存在TABLE ACCESS FULL行為,對於9i及以后版本,使用以下語句即可

select *
  from v$sql_plan v
where v.operation = 'TABLE ACCESS'
   and v.OPTIONS = 'FULL'
   and v.OBJECT_OWNER='MS';--指定用戶下

查詢得到SQL_ID,以及ADDRESS,HASH_VALUE,PLAN_HASH_VALUE,OBJECT_NAME后,就可以定位到具體的SQL語句了。

如:

select s.SQL_TEXT
  from v$sqlarea s
where s.SQL_ID = '4dpd97jh2gzsd'
   and s.HASH_VALUE = '1613233933'
   and s.PLAN_HASH_VALUE = '3592287464';

或者

select s.SQL_TEXT from v$sqlarea s where s.ADDRESS = '00000000A65D2318';


ORACLE優化之執行規划 - TABLE FULL SCAN/INDEX FULL SCAN

TABLE FULL SCAN :  全表掃描,表示表中所有記錄都被訪問到。如果表很大,  該操作對查詢性能的影響會很大,此時,建議使用索引  或去掉查詢中的LIKE操作。
 

如:
  EXPLAIN PLAN
   SET statement_id = 'ex_plan1' FOR
   SELECT phone_number FROM employees
   WHERE phone_number LIKE '650%';


INDEX RANGE SCAN [DESCENDING] :  從相關索引中獲取了一個或多個ROWID。  當查詢條件字段具有非唯一索引,或者查詢過濾條件是一個范圍,  ORACLE將會采用該操作。
 
  示例:
   SELECT * FROM t_employee WHERE id > 11001;
   SELECT * FROM t_employee WHERE first_name = 'Tommy';
  
   此例中,id是關鍵字,first_name具有非唯一索引。   oracle會對此兩個索引采用INDEX RANGE SCAN.
 
INDEX FULL SCAN [DESCENDING]:  從相關的索引中獲取了所有的ROWID。由於是按索引的順序訪問和獲取ROWID,  因此獲得的ROWID是直接排過序的。
 
  示例1:
   SELECT /*+ INDEX(T_EMPLOYEE IDX_NODES_ID)*/ id from T_EMPLOYEE;
 
   示例中使用了HINT要求強制使用索引查詢,但未指定索引字段的過濾條件,   於是ORACLE將采用INDEX FULL SCAN操作。由於該操作按索引順序或去記錄,   因而返回的ID列表是排過序的。
 
  示例2:
   SELECT * FROM T_EMPLOYEE WHERE MIDDLE_NAME IS NULL;
  
   當MIDDLE_NAME字段可以為NULL,且具有非唯一索引,ORACLE在執行此語句時,   可能會采用INDEX FULL SCAN操作。   但在某些情況下,比如該語句已經執行過一遍,相關數據已經加載到內存,   那么,ORACLE的執行規划也可能會直接選擇TABLE FULL SCAN操作,可能   是ORACLE認為此時直接TABLE FULL SCAN的性能會比INDEX FULL SCAN高。
 
INDEX FAST FULL SCAN
  從相關索引中獲取所有的ROWID。該操作同時從多個索引數據塊中掃描數據,  所以結果並不是排序的。用於對索引字段進行查詢。
 
  示例:SELECT id FROM T_EMPLOYEE;  其中id為表的主鍵索引字段。
 
 
優化策略:
  一般情況下,盡量避免FULL SCAN,特別是TABLE FULL SCAN和INDEX FULL SCAN.  在查詢大表的情況下,INDEX RANGE SCAN會顯著提高查詢性能。但在查詢小表時,  INDEX可能反而對性能產生不利影響。


oracle創建索引

數據庫索引是為了提高查詢速度的一種數據結構。

索引的創建語句

索引的創建語句非常簡單。

CREATE INDEX 索引名 ON 表名(列名);

除了單列索引,還可以創建包含多個列的復合索引。

CREATE INDEX 索引名 ON 表名(列名1, 列名2, 列名3, ...);

刪除索引也非常簡單。

DROP INDEX 索引名;

查看某個表中的所有索引也同樣簡單。

SELECT * FROM ALL_INDEXES WHERE TABLE_NAME = '表名'

還可以查看某個表中建立了索引的所有列。

SELECT * FROM ALL_IND_COLUMNS WHERE TABLE_NAME = '表名'

索引的建立原則

1.索引應該建立在WHERE子句中經常使用的列上。如果某個大表經常使用某個字段進行查詢,並且檢索的啊行數小於總表行數的5%,則應該考慮在該列上建立索引。

2.對於兩個表連接的字段,應該建立索引。

3.如果經常在某表的一個字段上進行Order By的話,則也應該在這個列上建立索引。

4.不應該在小表上建立索引。

索引的優缺點

索引主要是為了提高數據的查詢速度,這就是索引的優點。但是當進行增刪改的時候,會更新索引。因此索引越多,增刪改的速度就會越慢,因為有一個維護索引的過程。創建索引之前需要權衡該字段是否經常發生增刪改操作,否則可能會帶來負優化的問題。

索引的優點

1.很大地提高了數據的檢索速度。

2.創建唯一索引能保證數據庫表中每一行數據的唯一性(唯一性約束)。

3.提高表與表之間的連接速度。

索引的缺點

1.索引需要占用物理空間。

2.當對表中的數據進行增加、刪除和修改的時候,索引也要動態地進行維護,降低數據的維護速度。

關於查詢優化器

當Oracle拿到SQL語句的時候,會使用查詢優化器去分析該語句,並根據分析結果生成查詢執行計划。也就是說,數據庫是執行的查詢計划,而不是SQL語句。

查詢優化器有RBO(Rule-Based-Optimizer,基於規則的查詢優化器)和CBO(Cost-Based-Optimizer,基於成本的查詢優化器),其中基於規則的查詢優化器在10g的版本中徹底消失了。原因是因為RBO最后的查詢都是全表掃描,而CBO會根據統計信息選擇最優的查詢方案。

因此,CBO一旦發現有索引的存在,並且這個索引能幫助提高查詢速度,就是使用通過索引進行查詢的方法。

oracle 索引的幾種類型

1. b-tree索引
Oracle數據庫中最常見的索引類型是b-tree索引,也就是B-樹索引,以其同名的計算科學結構命名。CREATE
INDEX語句時,默認就是在創建b-tree索引。沒有特別規定可用於任何情況。
2. 位圖索引(bitmap index)
位圖索引特定於該列只有幾個枚舉值的情況,比如性別字段,標示字段比如只有0和1的情況。
3. 基於函數的索引
比如經常對某個字段做查詢的時候是帶函數操作的,那么此時建一個函數索引就有價值了。
4. 分區索引和全局索引
這2個是用於分區表的時候。前者是分區內索引,后者是全表索引
5. 反向索引(REVERSE)
這個索引不常見,但是特定情況特別有效,比如一個varchar(5)位字段(員工編號)含值
(10001,10002,10033,10005,10016..)
這種情況默認索引分布過於密集,不能利用好服務器的並行
但是反向之后10001,20001,33001,50001,61001就有了一個很好的分布,能高效的利用好並行運算。
6.HASH索引
HASH索引可能是訪問數據庫中數據的最快方法,但它也有自身的缺點。集群鍵上不同值的數目必須在創建HASH集群之前就要知道。需要在創建HASH集群的時候指定這個值。使用HASH索引必須要使用HASH集群。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM