2013-05-18 80 views
-1
PLAN_TABLE_OUTPUT 
-------------------------------------------------------------------------------- 
Plan hash value: 2822030489 
--------------------------------------------------------------------------------------------- 

| Id | Operation     | Name   | Rows | Bytes | Cost (%CPU)| Time  | 
--------------------------------------------------------------------------------------------- 
PLAN_TABLE_OUTPUT 
-------------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT   |    |  1 | 46 |  2 (0)| 00:00:01 | 
| 1 | TABLE ACCESS BY INDEX ROWID| PURCHASE  |  1 | 46 |  2 (0)| 00:00:01 | 
|* 2 | INDEX UNIQUE SCAN   | PK_PURCHASENO |  1 |  |  1 (0)| 00:00:01 | 
--------------------------------------------------------------------------------------------- 
PLAN_TABLE_OUTPUT 
-------------------------------------------------------------------------------- 

Predicate Information (identified by operation id): 
--------------------------------------------------- 
2 - access("PURCHASENO"=9989) 

14 rows selected. 

有人可以向我解釋這是什麼意思?Oracle優化器執行查詢

這是否意味着Oracle正在使用索引來執行此查詢?

+0

'PURCHASENO'是一個主鍵,它有一個唯一索引,所以是的 - oracle選擇一個索引訪問路徑。 – haki

+0

「INDEX UNIQUE SCAN」不是一個線索嗎?你看過[性能調整指南](http://docs.oracle.com/cd/E29597_01/server.1111/e16638/optimops.htm#i82029)嗎? –

+0

@AlexPoole是的,我只是想確保爲了完全回答這個問題。 – Jim

回答

1

線索在計劃中。

這意味着您唯一掃描了索引PK_PURCHASENO。

| Operation   | Name   | Rows | 
--------------------------------------------- 
| INDEX UNIQUE SCAN | PK_PURCHASENO |  1 | 

我假設名稱是這是您的主鍵,並通過您的查詢判斷它是在PURCHASENO列上。主鍵必須是唯一的,所以這並不令人意外。你注意到列表示你只返回一行,這證實了這一點.a

另一個重要的是這行。

| Id | Operation     | Name   | Rows | Bytes | 
--------------------------------------------------------------------- 
| 1 | TABLE ACCESS BY INDEX ROWID| PURCHASE  |  1 | 46 | 

你唯一掃描索引,但你不只是從索引中選擇數據,你也必須爲你寫select *從表中返回數據。 ROWID是表中標識行的唯一地址。通過ROWID訪問(單個)行是返回數據的最快方式。 Oracle在您的主鍵索引中找到所需的行,然後使用rowid來挑出行的其餘部分。您注意到字節的列有46個,這意味着該行的長度是46個字節。

是你,而不是使用下面的查詢將不再需要通過ROWID訪問:

select purchaseno 
    from purchase 
where purchaseno = 1000 

這是因爲列PURCHASENO已經在指數;沒有必要訪問表格。因此,select *被認爲是「有害的」,不僅增加了您必須從磁盤讀取的數據量以及可能需要通過網絡發送的數據量,還意味着您可能需要額外執行操作以訪問您的數據。只有選擇你需要的行。

最後兩點,在您的查詢中,值PUCRHASENO被括在引號中,儘管是一個數字。如果PURCHASENO實際上是一個角色,那麼這很好,但如果這是一個數字,那麼您就會冒險將這些角色轉換爲數字。甲骨文explicitly recommends against implicit conversion,原因如下:

  • SQL語句是容易當你使用顯式數據類型轉換函數理解。

  • 隱式數據類型轉換可能會對性能產生負面影響,尤其是如果將列值的數據類型轉換爲常數而非其他方式。

  • 隱式轉換取決於它發生的上下文,並且在每種情況下可能不會以相同的方式工作。例如,從日期時間值到VARCHAR2值的隱式轉換可能會返回意外的一年,具體取決於NLS_DATE_FORMAT 參數的值。

  • 隱式轉換的算法可能會在軟件版本和Oracle產品之間發生變化。顯式轉換的行爲更具可預測性。

這樣做可以混淆優化不夠,你使用索引,雖然這是不太可能和你的一樣簡單查詢的情況發生。

最後,這是個人偏好,我發現PURCHASE表的主鍵的名稱相當混亂。一個更好的標準是PK_<table name>而不是PK_<column name>一個表只能有一個主鍵,並且只有一個該名稱的對象可以在任何一個模式中。但是,可能有兩個表的列名與主鍵相同。

Oracle性能調優指南中有關於reading and understanding explain plans的一章,我強烈建議閱讀。

+0

非常感謝 – Jim