[20260120]关于sql_id没有那些字符.txt

来源:这里教程网 时间:2026-03-03 23:13:58 作者:

[20260120]关于sql_id没有那些字符.txt --//别人问的问题,sql_id是使用32进制,32进制仅仅需要10个数字+22个字母,这样有4个字符不会出现在sql_id中. --//sql_id的计算是使用MD5算法进行哈希,生成一个128位的Hash Value,其中低32位作为HASH VALUE显示,SQL_ID则取了后64位。 --//实际上sql_id使用32进制表示,hash_value使用10进制表示。 --//最简单的方法执行如下: SYS@book> with a as (select chr(level+96) txt from dual connect by level<=26) select a.txt from a where not exists (select 1 from v$sqlarea where instr(sql_id,a.txt)>0); TX -- e i l o with a as (select chr(level+96) txt from dual connect by level<=26) select txt from a minus select a.txt from a where exists (select 1 from v$sqlarea where instr(sql_id,a.txt)>0); TX -- e l o i --//可以推测ol与数字01太相近,比较容易混淆。一般编程都要求规避l,o作为变量.至于ei,估计也是一样的原因. --//补充说明: WITH a AS (    SELECT CHR (LEVEL + 96) txt FROM DUAL CONNECT BY LEVEL <= 26) SELECT txt FROM a MINUS SELECT a.txt FROM a WHERE EXISTS (SELECT /*+ NO_UNNEST */ 1 FROM v$sqlarea WHERE INSTR (sql_id, a.txt) > 0); --//开始以为第1种写法执行有点慢,实际的情况是第2种执行更慢。加入提示NO_UNNEST才快一些,真实的情况第1种写法最快。 --//更正以前我的理解not exist执行慢的情况,实际上前面的a表数据少是主要原因。 --//而且sql_id取64位,2^5表示1个32位,64/5=12.8(sql_id长度13个字符).剩下小于2^4表示sql_id第1个字符,最大编码1111(2进制) --//对应32位编码是g,这样sql_id第1个字符不会大于'h'. --//注意:e字符不在sql_id的32位进制编码中. SYS@book> select sql_id from v$sqlarea where substr(sql_id,1,1)>='h'; no rows selected --//通过bash shell分析: $ cat aa2.txt set head off feedback off spool aa1.txt select sql_id from v$sqlarea ; spool off @ aa2.txt ... $ diff  <(echo {0..9} {a..z}| tr ' ' '\n') <(grep -P  -o '.' aa1.txt | sort | uniq ) 15d14 < e 19d17 < i 22d19 < l 25d21 < o $ diff <(echo {0..9} {a..z}| grep  -o '[0-9a-z]') <(grep   -o '.' aa1.txt | sort | uniq ) 15d14 < e 19d17 < i 22d19 < l 25d21 < o --//可以看出sql_id不包括eilo4个字符。 $ diff <(echo {0..9} {a..z}| grep  -o '[0-9a-z]') <(grep   -o '.' aa1.txt | sort | uniq )| grep  -o '\b[a-z]$'   | paste -sd' ' e i l o

相关推荐