[20191011]通過bash計算sql語句的sql_id.txt
[20191011]通過bash計算sql語句的sql_id.txt
--//當我知道如何通過bash計算sql語句的full_hash_value ,就很想通過bash程式設計計算sql_id.當時受限自己能力
--//感覺不好實現.
--//連結: http://blog.itpub.net/267265/viewspace-2142512/=> [20170724]關於sql_id那些事.txt
1.簡單介紹sql_id.
--//sql_id的計算是使用MD5演算法進行雜湊,生成一個128位的Hash Value,其中低32位作為HASH VALUE顯示,SQL_ID則取了後64位。
--//實際上sql_id使用32進製表示,hash_value使用10進製表示。
2.環境:
SCOTT@book> @ &r/ver1
PORT_STRING VERSION BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx 11.2.0.4.0 Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
select * from emp where deptno=10;
--//查詢可以知道sql_id='557p4j1ggw222'.
SCOTT@book> select sql_text c70,sql_id,hash_value from v$sql where sql_id = '557p4j1ggw222';
C70 SQL_ID HASH_VALUE
---------------------------------- ------------- ----------
select * from emp where deptno=10 557p4j1ggw222 1593706562
SCOTT@book> select name c70,hash_value,full_hash_value from V$DB_OBJECT_CACHE where name like '%emp%' and hash_value=1593706562;
C70 HASH_VALUE FULL_HASH_VALUE
--------------------------------- ---------- --------------------------------
select * from emp where deptno=10 1593706562 8bb974871a4f8c88529ea4885efe0842
select * from emp where deptno=10 1593706562 8bb974871a4f8c88529ea4885efe0842
--//注以上是以前的測試!!
3.簡單說明如何計算sql_id:
--//簡單說明sql_id採用32進位制,編碼0-9,a-z.沒有eilo字元,這些字元容易與數字0,1混淆.
--//程式設計利用bc obase=32;ibase=16;輸出.通過陣列BASE32定位編碼.注意bc的輸出例子:
$ echo "obase=32;ibase=16; 529EA4885EFE0842" | bc| tr -d '\\\r\n'
05 05 07 21 04 17 01 15 15 28 02 02 02
--//這些數字是10進位制數字,前面雖然有0,不能寫成${BASE32[$i]},必須寫成{BASE32[$(( 10#$i ))]}.
$ ./sql_id.sh "select * from emp where deptno=10"
sql_text = select * from emp where deptno=10\0
full_hash_value(16) = 8BB974871A4F8C88529EA4885EFE0842
hash_value(10) = 1593706562
sql_id = 557p4j1ggw222
--//再測試一個例子:
SCOTT@test01p> select /*+ 12345678abdef */ sysdate from dual ;
SYSDATE
-------------------
2019-10-11 22:34:56
SCOTT@test01p> @ dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID 0p0rzks2gkrj6, child number 0
-------------------------------------
select /*+ 12345678abdef */ sysdate from dual
Plan hash value: 1388734953
------------------------------------------------------------------
| Id | Operation | Name | E-Rows | Cost (%CPU)| E-Time |
------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | 2 (100)| |
| 1 | FAST DUAL | | 1 | 2 (0)| 00:00:01 |
------------------------------------------------------------------
--//sql_id=0p0rzks2gkrj6,主要要找一個sql_id前面是0的情況.注意dual後面有1個空格.
$ ./sql_id.sh "select /*+ 12345678abdef */ sysdate from dual "
sql_text = select /*+ 12345678abdef */ sysdate from dual \0
full_hash_value(16) = EF5A2C4876C9E93D0A82FF9604F95E26
hash_value(10) = 83451430
sql_id(32) = 0p0rzks2gkrj6
--//完成能對上.
SCOTT@test01p> select name c70,hash_value,full_hash_value from V$DB_OBJECT_CACHE where hash_value=83451430;
C70 HASH_VALUE FULL_HASH_VALUE
--------------------------------------------- ---------- --------------------------------
select /*+ 12345678abdef */ sysdate from dual 83451430 ef5a2c4876c9e93d0a82ff9604f95e26
select /*+ 12345678abdef */ sysdate from dual 83451430 ef5a2c4876c9e93d0a82ff9604f95e26
4.總結:
--//我幾乎是一氣呵成寫成指令碼,當我回過頭看我寫的指令碼,感覺原來如此簡單.
--//自己真沒想到短短几行程式碼,就能實現這個功能.
5.指令碼如下:
$ cat sql_id.sh
#! /bin/bash
# calcucate sql_text of full_hash_value(16),hash_value(10),sql_id(32).
odebug=${ODEBUG:-0}
sql_text=${1}'\0'
v1=$(echo -e -n "$sql_text" | md5sum | sed 's/ -//' | xxd -r -p | od -t x4 | sed -n -e 's/^0\+ //' -e 's/ //gp' | tr 'a-z' 'A-Z')
v2=${v1:(-16):16}
v3=${v2:(-8):8}
# v2=$(echo "obase=16;ibase=16; $v1 % 10000000000000000" | bc| tr -d '\\\r\n')
# v3=$(echo "obase=10;ibase=16; $v1 % 100000000" | bc| tr -d '\\\r\n')
if [ $odebug -eq 1 ] ; then
echo v1=$v1 v2=$v2 v3=$v3
fi
echo "sql_text = $sql_text"
echo "full_hash_value(16) = $v1 "
echo "hash_value(10) = $(( 16#$v3 )) "
BASE32=($(echo {0..9} {a..z} | tr -d 'eilo'))
res=''
for i in $(echo "obase=32;ibase=16; $v2" | bc| tr -d '\\\r\n')
do
res=${res}${BASE32[$(( 10#$i ))]}
done
echo "sql_id(32) = $(printf "%13s" $res | tr ' ' '0')"
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-2659623/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [20211009]使用bash計算sql語句的sql_id.txtSQL
- [20191101]通過zsh計算sql語句的sql_id.txtSQL
- 通過分析SQL語句的執行計劃優化SQL語句SQL優化
- 通過sql語句分析足彩SQL
- 通過分析SQL語句的執行計劃優化SQL 二SQL優化
- 通過分析SQL語句的執行計劃優化SQL(總結)SQL優化
- oracle 通過sql profile為sql語句加hintOracleSQL
- 通過SQL PROFILE自動優化SQL語句SQL優化
- ORACLE 通過SPM為SQL語句加HINTOracleSQL
- 通過java來格式化sql語句JavaSQL
- 通過使用hint unnest調優sql語句SQL
- 通過java程式抽取日誌中的sql語句JavaSQL
- 通過SQL語句提取儲存過程中的內容SQL儲存過程
- 通過ORA錯誤反思sql語句規範SQL
- 通過sql語句分析足彩(第三篇)SQL
- 通過圖表簡化sql語句的表關聯SQL
- MySQL_通過binlog檢視原始SQL語句MySql
- 用 Phoenix 通過 SQL 語句更新操作 HBase 資料SQL
- 通過Linux命令過濾出binlog中完整的SQL語句LinuxSQL
- 通過日誌檢視mysql正在執行的SQL語句MySql
- 【轉】通過sql語句獲取資料庫的基本資訊SQL資料庫
- 【AWR】通過AWR報告中記錄的 SQL Id獲得SQL語句的執行計劃SQL
- SQL語句的處理過程SQL
- MySQL在ROW模式下通過binlog提取SQL語句MySql模式
- 通過pl/sql計算程式的執行時間SQL
- 透過sql語句分析足彩SQL
- CoreData執行過程的sql語句SQL
- SQL語句的處理過程修正SQL
- 剖析SQL語句的執行過程SQL
- Oracle SQL 語句的執行過程OracleSQL
- 統計介面sql語句SQL
- 透過分析SQL語句的執行計劃最佳化SQL(總結)SQL
- mysql執行sql語句過程MySql
- 通過_optimizer_rownum_pred_based_fkr優化一條sql語句優化SQL
- 一條sql語句的執行過程SQL
- 淺談SQL語句的執行過程SQL
- 理解oracle執行sql語句的過程OracleSQL
- 一條SQL語句的優化過程SQL優化