[20141205]关于sql_id.txt

[20141205]关于sql_id.txt

--昨天跟别人聊天,讲sql_id字串里面没有字符'o'.实际上他在学习sql_id与hash_value转换时copy 和 paste少粘贴1位,手工输入时以
--为是--字母'o',实际上是数字'0'.

--顺便找一个sql_id,把最后以为换成o,看看结果:
SYS@test> select dbms_utility.SQLID_TO_SQLHASH('f7nhbjdn5rx9o') from dual ;
select dbms_utility.SQLID_TO_SQLHASH('f7nhbjdn5rx9o') from dual
       *
ERROR at line 1:
ORA-13797: invalid SQL Id specified, f7nhbjdn5rx9o
ORA-06512: at "SYS.DBMS_UTILITY", line 1293

--做一个简单的查询:
SYS@test> select sql_id from v$sqlarea where instr(sql_id,'o')>0;
no rows selected

--很明显没有字符'o'.

--sql_id的计算是使用MD5算法进行哈希,生成一个128位的Hash Value,其中低32位作为HASH VALUE显示,SQL_ID则取了后64位。
--实际上sql_id使用32进制表示,hash_value使用10进制表示。

--既然使用32进制,0-9,a-z 总共10+26=36个字符,明显多了4个。也就是讲有4个字符不会出现在sql_id中。

--写一个简单的sql看看。

select b.x from (select chr(level+96) x from dual connect by level  2  where instr(sql_id,b.x)>0);
X
---
e
i
l
o

--还包括eilo 4个字符。看看大师写的sql_id转换hash_value的语句就知道了。

http://blog.tanelpoder.com/2009/02/22/sql_id-is-just-a-fancy-representation-of-hash-value

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 /

--转换表里面没有eilo。脚本乍看有点晕,实际上很简单。实际的思路是把sql_id当作32进制,先取出单个字符,然后转成10进制,
--然后全部加起来,再与power(2,32)取mod ,结果就是hash_value.展开看看:

SYS@test> select sql_id,hash_value from v$sqlarea where rownumSQL_ID        HASH_VALUE
------------- ----------
1fkh93md0802n 3657695316

SELECT 14-level,
    '&1' sql_id,
           SUBSTR ('&1', LEVEL, 1) x1,
           INSTR ('0123456789abcdfghjkmnpqrstuvwxyz', SUBSTR ('&1', LEVEL, 1)) - 1  x2 ,
           (INSTR ('0123456789abcdfghjkmnpqrstuvwxyz', SUBSTR ('&1', LEVEL, 1)) - 1)*power(32,length('&1')-level) x3
      FROM DUAL
CONNECT BY LEVEL 13 rows selected.

14-LEVEL SQL_ID        X1  X2                   X3
-------- ------------- -- --- --------------------
      13 1fkh93md0802n 1    1  1152921504606846976
      12 1fkh93md0802n f   14   504403158265495552
      11 1fkh93md0802n k   18    20266198323167232
      10 1fkh93md0802n h   16      562949953421312
       9 1fkh93md0802n 9    9        9895604649984
       8 1fkh93md0802n 3    3         103079215104
       7 1fkh93md0802n m   19          20401094656
       6 1fkh93md0802n d   13            436207616
       5 1fkh93md0802n 0    0                    0
       4 1fkh93md0802n 8    8               262144
       3 1fkh93md0802n 0    0                    0
       2 1fkh93md0802n 2    2                   64
       1 1fkh93md0802n n   20                   20
13 rows selected.

select mod(sum(x3),power(2,32)) from (
    SELECT 14-level,
    '&1' sql_id,
           SUBSTR ('&1', LEVEL, 1) x1,
           INSTR ('0123456789abcdfghjkmnpqrstuvwxyz', SUBSTR ('&1', LEVEL, 1)) - 1  x2 ,
           (INSTR ('0123456789abcdfghjkmnpqrstuvwxyz', SUBSTR ('&1', LEVEL, 1)) - 1)*power(32,length('&1')-level) x3
      FROM DUAL
CONNECT BY LEVEL

MOD(SUM(X3),POWER(2,32))
------------------------
              3657695316

--这样就很好理解了。

--而且sql_id取64位,2^5表示1个32位,剩下小于2^4表示sql_id第1个字符,这样sql_id第1个字符不会大于'h'.
SYS@test> select sql_id from v$sqlarea where substr(sql_id,1,1)>='h';
no rows selected

--为什么去掉eilo,我不知道,我的感觉就是去掉lo,主要可能就是它与数字01太相近,比较容易混淆。一般编程都要求规避l,o作为变
--量.至于ei,估计也是一样的原因,纯粹是我自己乱猜...................

时间: 2024-09-20 20:18:26

[20141205]关于sql_id.txt的相关文章

[20141212]关于sql_id.txt

[20141212]关于sql_id.txt http://blog.itpub.net/267265/viewspace-1357292/ http://blog.itpub.net/267265/viewspace-1220996/ --昨天别人问一些sql_id计算的问题,实际上我也不懂具体的算法,我给他看了上面的链接. --他问的问题,还是通过例子来说明: SCOTT@test> @ver1 PORT_STRING                    VERSION        BA

[20150616]关于sql_id.txt

[20150616]关于sql_id.txt --我曾经提到PLSQL中使用绑定变量,oracle会格式化处理,转化为特定的格式.可以参考我以前的例子: --[20121102]PLSQL中的绑定变量.txt --http://blog.itpub.net/267265/viewspace-748190/ --我也曾经写过一篇exact_matching_signature,force_matching. --http://blog.itpub.net/267265/viewspace-1220

[20131217]从sql语句计算sql_id.txt

[20131217]从sql语句计算sql_id.txt 这个方面的内容从网上能找到许多,从sql语句可以检查出sql_id的值以及HASH_VALUE的值. http://www.johnnydb.com/2012/03/sql_id-vs-hash_value/www.dbthink.com/?p=321 自己做一些测试以及总结,记录一些简单的方法在11G下: SYS@test> @verBANNER----------------------------------------------

[20160323]关于FULL_HASH_VALUE2.txt

[20160323]关于FULL_HASH_VALUE2.txt --前一阵子firefox遇到问题,测试插件Calculate Hash.链接: http://blog.itpub.net/267265/viewspace-2023144/ --实际上许多工具命令是相同的,linux下也有一个命令md5sum也可以拿来计算FULL_HASH_VALUE.测试看看: 1.环境: SCOTT@book> @ &r/ver1 PORT_STRING                    VERS

[20170724]关于sql_id那些事.txt

[20170724]关于sql_id那些事.txt --//昨天别人问的问题,我以前也写过许多blog,做一些总结: http://blog.itpub.net/267265/viewspace-1357292/ http://blog.itpub.net/267265/viewspace-1365382/ http://blog.itpub.net/267265/viewspace-1701985/ 1.环境: SCOTT@book> @ &r/ver1 PORT_STRING      

[20150803]无法通过sql_id找到sql语句3.txt

[20150803]无法通过sql_id找到sql语句3.txt --前一阵子,在做优化时遇到1个无法通过sql_id找到sql语句的情况: http://blog.itpub.net/267265/viewspace-1749265/ --就是因为共享池太小,执行次数少,没到取样时间,已经从共享池清除. --今天自己google,想想看看还有那种情况会出现呢?如果1条语句执行错误,会记录sql_id,当时查询v$sql视图应该也不能找到. --自己直接那生产系统看看: 1.建立测试环境: --

[20141205]参数引号大小写问题.txt

[20141205]参数引号大小写问题.txt --前几天在做dataguard时遇到修改参数的一些小问题,这些小问题有时候很浪费时间,看来做dba有时候需要一副好眼睛. [20140529]11g下参数audit_trail的修改.txt=> http://blog.itpub.net/267265/viewspace-1172182/ [20141202]关于参数的修改问题.txt => http://blog.itpub.net/267265/viewspace-1353703/ --自

[20140807]hash_value sql_id冲突.txt

[20140807]hash_value sql_id冲突.txt --9i下使用v$sql仅仅有hash_value值,sql_id是到10g下才出现. --理论讲hash_values是sql_id的子集,发生冲突的可能性比使用sql_id,看了链接重复测试: http://externaltable.blogspot.com/2012/06/hash-collisions-sql-signatures-and.html SCOTT@test> @ver BANNER -----------

[20171031]markhot.txt

[20171031]markhot.txt --//昨天看了https://jonathanlewis.wordpress.com/2017/10/02/markhot/,测试看看这样时候可以减少争用. 1.环境: SCOTT@book> @ &r/ver1 PORT_STRING                    VERSION        BANNER ------------------------------ -------------- -------------------