[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
台州市网站建设_网站建设公司_Figma_seo优化