簡體   English   中英

Oracle中如何查看索引是否被使用

[英]How to check whether index is being used or not in Oracle

SELECT * 
FROM   (SELECT TEMP.*, 
               ROWNUM RNUM 
        FROM   (SELECT entry_guid 
                FROM   alertdevtest.ENTRY 
                WHERE  Upper(alert_name) = 'alertname' 
                       AND user_guid = 'AlertProductClientTest' 
                       AND product_code = '-101' 
                       AND status_code != 13) TEMP 
        WHERE  ROWNUM <= 2500) 
WHERE  rnum >= 0; 

SELECT * 
FROM   (SELECT TEMP.*, 
               ROWNUM RNUM 
        FROM   (SELECT entry_guid 
                FROM   alertdevtest.ENTRY 
                WHERE  Upper(alert_name) = 'alertname' 
                       AND user_guid = 'AlertProductClientTest' 
                       AND product_code = '-101' 
                       AND status_code != 13 
                       AND product_view IN ( 'PView' )) TEMP 
        WHERE  ROWNUM <= 2500) 
WHERE  rnum >= 0; 

我正在運行上述查詢,發現第二個查詢與第一個查詢相比性能下降。 唯一的區別是第二個查詢中的附加過濾器和 PRODUCT_VIEW IN ('PView')。 但它在該列上有索引。 請讓我知道性能下降的原因是什么以及如何檢查索引是否被使用? 我正在使用 Oracle SQL 開發人員並嘗試檢查解釋計划但無法獲得更多詳細信息。

在Oracle SQL Developer中,當工作表中包含SQL時,會有一個“說明計划”按鈕,您也可以按F10鍵。 執行Explain計划后,它將顯示在SQL Developer的底部視圖中。 有一列“ OBJECT_NAME”,它將告訴您正在使用什么索引。 例如,在我剛運行的查詢中,左列(OPERATION)首先顯示“ SELECT STATEMENT”,然后顯示SORT(AGGREGATE),然后顯示INDEX(RANGE SCAN),然后在OBJECT_NAME列中顯示TICKER_IDX1,即我表上索引的名稱。

因此,您可以通過OBJECT_NAME列查看正在使用的索引。

Oracle基於成本的優化器可能會選擇次優的執行計划。 許多次更新統計信息將解決此問題。 其他選擇是添加其他索引,換句話說就是多列索引。 您可以提示一條SQL語句,但這很少需要。 另外,可以重寫查詢。

EXPLAIN PLAN語句是檢查執行計划的最佳方法。 圖形執行計划被認為是有害的。

EXPLAIN PLAN對於執行計划的常見圖形表示, EXPLAIN PLAN具有許多優點:

  1. 簡單,標准格式的 DBMS_XPLAN.DISPLAY可在任何環境中工作,並產生Oracle專業人員所熟悉的輸出。 有權使用Oracle的任何人都可以重現該問題,並且每個人都可以使用相同的標准名稱討論該問題。 SQL Developer可能是免費的,但大多數開發人員和DBA都不使用它。
  2. 易於處理輸出輸出易於保存和共享-將輸出存儲在表格中,將文本復制到記事本中,等等。使用WinMerge之類的程序進行比較也更加容易。 大型查詢可能會在執行計划中產生數百行,使用diff實用程序可使調整變得更加容易。 對於編程任務,文本勝於圖片。
  3. 包括重要部分由於某些奇怪的原因,IDE從未在執行計划中包括“ Note部分。 該部分通常包含重要信息。 在您的示例中,DBA可能為其中一個查詢而不是其他查詢固定了SQL Plan Baseline。 如果沒有“ Notes部分,我們只需要猜測是否發生了奇怪的事情。
  4. 更准確一些工具使用單獨的會話來生成圖形執行計划並產生錯誤的結果。 例如,如果沒有alter session enable parallel dml; ,計划可能會大不相同alter session enable parallel dml; 對於SQL Developer來說這似乎不是問題,但是我在其他程序中已經看到了。
  5. 可以編寫更強大的 DBMS_XPLAN腳本,並具有許多強大的功能,例如format => '+outline'dbms_xplan.display_awr等。

以下是EXPLAIN PLAN的簡單示例。 這個計划很好,但是它確實有一個巨大的危險信號,大多數圖形執行計划都不會顯示。 最后一行,使用的dynamic statistics used: dynamic sampling (level=2)表示其中一個表缺少優化器統計信息。

drop table test1;
create table test1(a number);
explain plan for insert into test1 select * from test1;
select * from table(dbms_xplan.display);

Plan hash value: 4122059633

----------------------------------------------------------------------------------
| Id  | Operation                | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------
|   0 | INSERT STATEMENT         |       |     1 |    13 |     2   (0)| 00:00:01 |
|   1 |  LOAD TABLE CONVENTIONAL | TEST1 |       |       |            |          |
|   2 |   TABLE ACCESS FULL      | TEST1 |     1 |    13 |     2   (0)| 00:00:01 |
----------------------------------------------------------------------------------

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)

快速檢查可以輕松按F10,F5,Ctrl + E或您特定IDE中的任何快捷鍵。 但是對於要與他人共享的嚴肅分析,請始終使用EXPLAIN PLAN

了解性能低下的原因的最好的辦法是獲取SQL * Trace。 有多種啟用跟蹤的方法http://docs.oracle.com/cd/B19306_01/server.102/b14211/sqltrace.htm#g33356例如

EXECUTE DBMS_SESSION.SESSION_TRACE_ENABLE(waits => TRUE, binds => TRUE);

您需要啟用跟蹤,運行這些查詢,最后獲取數據(因為通常Oracle在獲取期間執行大部分工作),關閉會話(需要關閉游標以使帶有時間統計信息的執行計划出現在跟蹤文件中)。
然后,您應該轉到數據庫服務器上的轉儲文件夾,獲取跟蹤文件,使用tkprof實用程序將其轉換為更具可讀性的方式,在其中找到這些查詢,然后享受:)。
SQL Trace的好處在於,它提供了在SQL執行過程中使用的真實計划,並且為計划的每個步驟提供了非常精確的時間,讀取,獲取,一致讀取,cpu統計信息(不幸的是,我不知道任何其他工具可以可以做到)。
缺點是您需要特權才能開始跟蹤,並且需要訪問轉儲文件夾(或者您需要讓DBA使用跟蹤來執行查詢,並且需要服務器管理員來獲取文件)。
更粗糙的選擇是啟用對此SQL的監視(例如,通過/ * + monitor * /提示)並使用DBMS_SQLTUNE.REPORT_SQL_MONITOR http://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_sqltun.htm #CHDBHIBG-可能會為執行計划的每個步驟生成帶有統計信息的漂亮HTML(例如在SQL Trace中)
優點是易於使用(您無需訪問服務器文件夾即可使用此功能)。
缺點是這種情況下的統計數據通常為1秒,因此僅對長時間運行的查詢(10秒或更長時間)有用。
如果僅需要檢查在SQL執行期間是否使用了索引,則可以查詢v $ sql_plan視圖和v $ sql,v $ sql_monitor視圖以找到適當的計划。

您可以運行此查詢來檢查索引的使用情況。

select ius.* , 
(select  sum(trunc(bytes / 1024 / 1024/ 1024  ,2)) 
 from dba_segments sgm 
 where  sgm.owner = ius.OWNER
   and sgm.segment_name = ius.name ) Used_Space 
   ,ind.DISTINCT_KEYS, ind.Total_Ind_Rows , ind.Total_Leaf_Block,
   trunc((ius.bucket_0_access_count / nullif(ius.total_access_count,0)) *100 ,2)Access_0_PCT,
   trunc((ius.bucket_1_access_count / nullif(ius.total_access_count,0)) *100 ,2) Access_1_PCT,
   trunc((ius.bucket_2_10_access_count / nullif(ius.total_access_count,0)) *100,2) Access_2_10_PCT,
   trunc((ius.bucket_11_100_access_count / nullif(ius.total_access_count,0)) *100,2) Access_11_100_PCT,
   trunc((ius.bucket_101_1000_access_count / nullif(ius.total_access_count,0)) *100,2) Access_101_1000_PCT,
   trunc((ius.bucket_1000_plus_access_count / nullif(ius.total_access_count,0)) *100,2) Access_1000_plus_PCT
from dba_index_usage ius , 
 (select ind.OWNER,ind.INDEX_NAME,ind.DISTINCT_KEYS, sum(ind.num_rows)Total_Ind_Rows,sum(ind.LEAF_BLOCKS)Total_Leaf_Block,
         trunc(sum(ind.num_rows)/nullif(sum(ind.LEAF_BLOCKS),0),2) RowsInBlocks
  from all_indexes ind 
  where ind.owner = &SchemaName
  group by ind.OWNER,ind.INDEX_NAME,ind.DISTINCT_KEYS
  ) ind
where ius.owner = &SchemaName 
  and ius.name = ind.INDEX_NAME

此外,您可以添加 v$sql_plan 和 dba_hist_sql_plan 來過濾未使用的索引。

and not exists 
      (select 'x'
       from v$sql_plan pln
       where  pln.OPERATION = 'INDEX'
        and pln.OBJECT_OWNER = ius.owner
        and pln.OBJECT_NAME = ius.name)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM