一次SQL_ID和HASH_VALUE转换尝试引发的误区(二)

2014-11-24 08:38:48 · 作者: · 浏览: 10
hysically still organized by the hash value, not SQL_ID. When you query views like X$KGLOB or V$SQL by SQL_ID, then Oracle just extracts the low 4 bytes from the SQL_ID and still does the lookup by hash value.

So, despite only SQL_ID showing up everywhere in Enterprise Manager and newest Oracle views and scripts, the hash_value isn’t going anywhere, it’s a fundamental building block of the library cache hash table.“

即尽管10g以后通常使用SQL_ID代表一条SQL,但实际上库缓存物理上还是使用HASH_VALUE组织的。使用SQL_ID查询X$KGLOB或V$SQL视图时,Oracle也是仅仅抽取出SQL_ID的低4个字节,仍旧通过HASH_VALUE值进行检索的。

因此,尽管在EM以及Oracle视图和脚本中到处可见SQL_ID,但实际HASH_VALUE仍起着作用,它才是构建库缓存哈希表的基础。

他也给出了一个用于SQL_ID和HASH_VALUE转换的脚本,用的就是如下SQL:

select
    lower(trim('&1')) sql_id
  , trunc(mod(sum((instr('0123456789abcdfghjkmnpqrstuvwxyz',substr(lower(trim('&1')),level,1))-1)
                       *power(32,length(trim('&1'))-level)),power(2,32))) hash_value
from
    dual
connect by
    level <= length(trim('&1'))
/
现在我们就能知道instr中这一串的字符是什么意思了,其实就是base-32转码的可见字符。也就能说明文章开始的两条SQL为什么看似相同,但结果不同了,其实就是base-32转码使用的不对。

总结

凡事都有因果,开始碰到这么一条SQL时,想当然认为就是0-9,a-z连续的字符,但其实这里用到的是base-32转码,并不是连续的字符,因此理解其背后的原理,才有助于清楚这里为什么这么用,而不是那么用。