當我們在Oracle中執行任何sql語句時,散列值正被分配給該sql語句並存儲到庫緩存中。所以,以後,如果另一個用戶請求相同的查詢,那麼Oracle將查找散列值並執行相同的執行計劃。但是,我對散列值有一個疑問。我的意思是,哈希值如何生成?,我的意思是,Oracle服務器是否使用某些算法,或者他們只是將sql字符串轉換爲某個數字值。sql語句的散列值
,因爲我讀專業的Oracle SQL書,在其上撰文指出,
select * from employees where department_id = 60;
SELECT * FROM EMPLOYEES WHERE DEPARTMENT_ID = 60;
select /* a_comment */ * from employees where department_id = 60;
將返回不同的散列值,因爲SQL語句執行時,那麼Oracle首先將字符串轉換爲哈希值。但是,當我嘗試這個,然後它返回相同的哈希值。
SQL> select * from boats where bid=10;
no rows selected
Execution Plan
----------------------------------------------------------
Plan hash value: 2799518614
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 16 | 1 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| BOATS | 1 | 16 | 1 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | B_PK | 1 | | 0 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("BID"=10)
SQL> SELECT * FROM BOATS WHERE BID=10;
no rows selected
Execution Plan
----------------------------------------------------------
Plan hash value: 2799518614
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 16 | 1 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| BOATS | 1 | 16 | 1 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | B_PK | 1 | | 0 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("BID"=10)
這意味着,這兩個sql語句應該有不同的散列值。而且,根據Oracle的說法,如果散列值在庫緩存中不可用,它將重新解析併爲sql語句生成新的計劃?不是嗎? – Ravi
@jWeavers - 正確。我更新了示例以顯示'sql_id'之外的'hash_value'。 'hash_value'有點老派,'plan_id'更容易用作標識符而不是使用'address'和'hash_value'。較新的數據字典表(如AWR表)使用'sql_id'而不是'hash_value'。 –