[20190423]那個更快的疑問3.txt
[20190423]那個更快的疑問3.txt
--//前一陣子,做了11g在單表單條記錄唯一索引掃描的測試,摘要如下:
--//參考連結:
http://blog.itpub.net/267265/viewspace-2636321/
http://blog.itpub.net/267265/viewspace-2636342/
--//在連結中我解析唯一索引查詢的情況,為什麼10g快於11g,連結:http://blog.itpub.net/267265/viewspace-2639920/
--//差異在於10g很少做times的系統呼叫上.10g下僅僅116次.而11g高達200179.(getrusage與times呼叫次數比大約是7:2)
--//我當時的感覺10g漏寫times系統函式呼叫,導致這樣的情況,11g把它補上了。
--//實際上有網友提出疑問.我的測試下的結論有問題.當時測試的情況如下:
--//11g的測試:
$ strace -f -c sqlplus -s -l scott/book @m1.txt 1e5 id=1_unique_index 0 >/dev/null
...
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
72.78 0.043919 0 700708 getrusage
19.80 0.011947 0 200179 times
6.67 0.004024 671 6 3 wait4
0.24 0.000147 29 5 clone
0.18 0.000106 0 375 2 read
0.16 0.000096 0 264 106 open
...
------ ----------- ----------- --------- --------- ----------------
100.00 0.060341 902967 206 total
--//1e5次執行times呼叫消耗0.011947秒,放大10倍(我每個session執行次數是1e6)也就是0.119470秒,什麼可能產生這麼大的差異.
--//仔細檢視,我覺得strace跟蹤記錄的syscallsyscall.linux標準C函式.看不出oracle內部函式呼叫次數.
--//我當時的解析是這增加的times呼叫一定是11g版本唯一索引掃描中增加幾個oracle內部函式呼叫,導致11g的唯一索引
--//掃描更慢,如何驗證我當時確實不知道? 最近shared latch測試,建立一些gdb指令碼,有了這些指令碼可以latch獲得釋放的情況.
1.環境:
SCOTT@book> @ 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
2.建立測試指令碼:
create table t as select rownum id from dual ;
create unique index pk_t on t(id);
alter table t modify id not null ;
create table job_times (sid number, time_ela number,method varchar2(20));
--//分析表略.
$ cat z1.txt
set verify off
host sleep $(echo &&3/50 | bc -l )
variable vmethod varchar2(20);
exec :vmethod := '&&2';
insert into job_times values ( sys_context ('userenv', 'sid') ,dbms_utility.get_time ,:vmethod) ;
commit ;
declare
v_id number;
v_d date;
begin
for i in 1 .. &&1 loop
select /*+ &&3 */ count (*) into v_id from t where id=1 ;
end loop;
end ;
/
update job_times set time_ela = dbms_utility.get_time - time_ela where sid=sys_context ('userenv', 'sid') and method=:vmethod;
commit;
quit
3.分別測試:
$ sqlplus -s -l scott/book @z1.txt 1e6 id=unindex 0 >/dev/null
SCOTT@book> Select method,count(*),round(avg(TIME_ELA),0),sum(TIME_ELA) from job_times group by method order by 3 ;
METHOD COUNT(*) ROUND(AVG(TIME_ELA),0) SUM(TIME_ELA)
-------------------- ---------- ---------------------- -------------
id=unindex 1 2723 2723
--//在10g下重複測試:
SCOTT@test> @ &r/ver1
PORT_STRING VERSION BANNER
------------------------------ -------------- ----------------------------------------------------------------
x86_64/Linux 2.4.xx 10.2.0.4.0 Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
SCOTT@test> select method,count(*),round(avg(TIME_ELA),0),sum(TIME_ELA) from job_times group by method order by 3 ;
METHOD COUNT(*) ROUND(AVG(TIME_ELA),0) SUM(TIME_ELA)
-------------------- ---------- ---------------------- -------------
id=unindex 1 1591 1591
--//即使單使用者執行10g下比11g快許多.
3.透過gdb指令碼分析:
--//11g:
SCOTT@book> @ spid
SID SERIAL# PROCESS SERVER SPID PID P_SERIAL# C50
---------- ---------- ------------------------ --------- ------ ------- ---------- --------------------------------------------------
88 89 65066 DEDICATED 65067 30 65 alter system kill session '88,89' immediate;
--//執行多次3次以上避免遞迴.
select count(*) from t where id=1;
--//開啟window 2:
$ gdb -p 65067 -x latch11g.gdb
(gdb) c
Continuing.
ksl_get_shared_latch laddr:85f7fe28, willing:1, where:-2050764096, why:95, mode:8
ksl_get_shared_latch laddr:85f7fe28, willing:1, where:-2050764096, why:96, mode:16
ksl_get_shared_latch laddr:85f7fe28, willing:1, where:-2050764096, why:95, mode:8
kslgetl 844ed538, 0, 49, 2062
kslgetl 8353a258, 1, 16777771, 2053
ksl_get_shared_latch laddr:85f7fe28, willing:1, where:-2050764096, why:96, mode:16
ksl_get_shared_latch laddr:85f7fe28, willing:1, where:-2050764096, why:95, mode:8
ksl_get_shared_latch laddr:85f7fe28, willing:1, where:-2050764096, why:96, mode:16
--//看到ksl_get_shared_latch 6次,kslgetl 2次,看看是什麼latch.
> select addr,name,level#,latch#,gets,misses,sleeps,immediate_gets,immediate_misses,waiters_woken,waits_holding_latch,spin_gets,wait_time from v$latch_children where addr=lpad(upper('85f7fe28'),'16','0')
ADDR NAME LEVEL# LATCH# GETS MISSES SLEEPS IMMEDIATE_GETS IMMEDIATE_MISSES WAITERS_WOKEN WAITS_HOLDING_LATCH SPIN_GETS WAIT_TIME
---------------- ---------------- ------ ---------- ---------- ---------- ---------- -------------- ---------------- ------------- ------------------- ---------- ----------
0000000085F7FE28 session idle bit 1 14 1095 0 0 0 0 0 0 0 0
--//session idle bit 第一次看見,我看了我的測試機器,一共24次children latch.估計跟CPU數量有關.我在另外的會話重複測試
--//ksl_get_shared_latch的地址不一樣,而kslgetl 也是2次都是一樣.
> select addr,name,level#,latch#,gets,misses,sleeps,immediate_gets,immediate_misses,waiters_woken,waits_holding_latch,spin_gets,wait_time from v$latch_children where addr=lpad(upper('844ed538'),'16','0')
ADDR NAME LEVEL# LATCH# GETS MISSES SLEEPS IMMEDIATE_GETS IMMEDIATE_MISSES WAITERS_WOKEN WAITS_HOLDING_LATCH SPIN_GETS WAIT_TIME
---------------- ------------------- ------ ---------- ---------- ---------- ---------- -------------- ---------------- ------------- ------------------- ---------- ----------
00000000844ED538 simulator lru latch 6 185 560 1 0 72795239 3207148 0 0 1 0
> select addr,name,level#,latch#,gets,misses,sleeps,immediate_gets,immediate_misses,waiters_woken,waits_holding_latch,spin_gets,wait_time from v$latch_children where addr=lpad(upper('8353a258'),'16','0')
ADDR NAME LEVEL# LATCH# GETS MISSES SLEEPS IMMEDIATE_GETS IMMEDIATE_MISSES WAITERS_WOKEN WAITS_HOLDING_LATCH SPIN_GETS WAIT_TIME
---------------- -------------------- ------ ---------- ---------- ---------- ---------- -------------- ---------------- ------------- ------------------- ---------- ----------
000000008353A258 simulator hash latch 7 186 72792634 0 0 0 0 0 0 0 0
--//奇怪這兩個latch我從來沒有過,而且奇怪的是根本看不到cbc latch.
--//在10g下重複測試看看(注10g shared latch 的函式是kslgetsl )
Breakpoint 1 at 0x7a0644
Breakpoint 2 at 0x7a0a44
Breakpoint 3 at 0x3bccd52
Breakpoint 4 at 0x3be9a04
Breakpoint 5 at 0x3181cd6400
Breakpoint 6 at 0x78ef44
Function "ksl_get_shared_latch" not defined.
Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]
Breakpoint 7 at 0x78f4bc
Breakpoint 8 at 0x79054c
--//奇怪10g沒有ksl_get_shared_latchoracle內部函式.註解這部分內容.
(gdb) c
Continuing.
kslgetsl laddr:7cfb24f8, willing:1, where:2096584384, why:80, mode:8
kslgetsl laddr:7cfb24f8, willing:1, where:2096584384, why:81, mode:16
kslgetsl laddr:7cfb24f8, willing:1, where:2096584384, why:80, mode:8
kslgetl 7a10aaa0, 1, 0, 2741
kslgetsl laddr:7cfb24f8, willing:1, where:2096584384, why:81, mode:16
kslgetsl laddr:7cfb24f8, willing:1, where:2096584384, why:80, mode:8
kslgetsl laddr:7cfb24f8, willing:1, where:2096584384, why:81, mode:16
--//看到kslgetsl 6次,kslgetl 1次,看看是什麼latch.
SYS@test> select addr,name,level#,latch#,gets,misses,sleeps,immediate_gets,immediate_misses,waiters_woken,waits_holding_latch,spin_gets,wait_time from v$latch_children where addr=lpad(upper('7cfb24f8'),'16','0');
ADDR NAME LEVEL# LATCH# GETS MISSES SLEEPS IMMEDIATE_GETS IMMEDIATE_MISSES WAITERS_WOKEN WAITS_HOLDING_LATCH SPIN_GETS WAIT_TIME
---------------- -------------------- ------ ---------- ---------- ---------- ---------- -------------- ---------------- ------------- ------------------- ---------- ----------
000000007CFB24F8 session idle bit 1 7 7112 0 0 0 0 0 0 0 0
SYS@test> select addr,name,level#,latch#,gets,misses,sleeps,immediate_gets,immediate_misses,waiters_woken,waits_holding_latch,spin_gets,wait_time from v$latch_children where addr=lpad(upper('7a10aaa0'),'16','0');
ADDR NAME LEVEL# LATCH# GETS MISSES SLEEPS IMMEDIATE_GETS IMMEDIATE_MISSES WAITERS_WOKEN WAITS_HOLDING_LATCH SPIN_GETS WAIT_TIME
---------------- ---------------------- ------ ---------- ---------- ---------- ---------- -------------- ---------------- ------------- ------------------- ---------- ----------
000000007A10AAA0 shared pool simulator 8 241 146325 1 0 0 0 0 0 1 0
--//你可以再次執行sql語句看看gets的變化:
SYS@test> select addr,name,level#,latch#,gets,misses,sleeps,immediate_gets,immediate_misses,waiters_woken,waits_holding_latch,spin_gets,wait_time from v$latch_children where addr=lpad(upper('7cfb24f8'),'16','0');
ADDR NAME LEVEL# LATCH# GETS MISSES SLEEPS IMMEDIATE_GETS IMMEDIATE_MISSES WAITERS_WOKEN WAITS_HOLDING_LATCH SPIN_GETS WAIT_TIME
---------------- ---------------- ------ ---------- ---------- ---------- ---------- -------------- ---------------- ------------- ------------------- ---------- ----------
000000007CFB24F8 session idle bit 1 7 7118 0 0 0 0 0 0 0 0
SYS@test> select addr,name,level#,latch#,gets,misses,sleeps,immediate_gets,immediate_misses,waiters_woken,waits_holding_latch,spin_gets,wait_time from v$latch_children where addr=lpad(upper('7a10aaa0'),'16','0');
ADDR NAME LEVEL# LATCH# GETS MISSES SLEEPS IMMEDIATE_GETS IMMEDIATE_MISSES WAITERS_WOKEN WAITS_HOLDING_LATCH SPIN_GETS WAIT_TIME
---------------- --------------------- ------ ---------- ---------- ---------- ---------- -------------- ---------------- ------------- ------------------- ---------- ----------
000000007A10AAA0 shared pool simulator 8 241 146326 1 0 0 0 0 0 1 0
--//說明跟蹤到的get變化沒有問題.我在11g看了latch的變化,只不過simulator lru latch 變成了IMMEDIATE_GETS數量增加:
> select addr,name,level#,latch#,gets,misses,sleeps,immediate_gets,immediate_misses,waiters_woken,waits_holding_latch,spin_gets,wait_time from v$latch_children where addr=lpad(upper('8353a258'),'16','0')
ADDR NAME LEVEL# LATCH# GETS MISSES SLEEPS IMMEDIATE_GETS IMMEDIATE_MISSES WAITERS_WOKEN WAITS_HOLDING_LATCH SPIN_GETS WAIT_TIME
---------------- ---------------------------------------- ---------- ---------- ---------- ---------- ---------- -------------- ---------------- ------------- ------------------- ---------- ----------
000000008353A258 simulator hash latch 7 186 72792639 0 0 0 0 0 0 0 0
> select addr,name,level#,latch#,gets,misses,sleeps,immediate_gets,immediate_misses,waiters_woken,waits_holding_latch,spin_gets,wait_time from v$latch_children where addr=lpad(upper('844ed538'),'16','0')
ADDR NAME LEVEL# LATCH# GETS MISSES SLEEPS IMMEDIATE_GETS IMMEDIATE_MISSES WAITERS_WOKEN WAITS_HOLDING_LATCH SPIN_GETS WAIT_TIME
---------------- ---------------------------------------- ---------- ---------- ---------- ---------- ---------- -------------- ---------------- ------------- ------------------- ---------- ----------
00000000844ED538 simulator lru latch 6 185 563 1 0 72795248 3207148 0 0 1 0
--//執行sql語句再檢視.
> select addr,name,level#,latch#,gets,misses,sleeps,immediate_gets,immediate_misses,waiters_woken,waits_holding_latch,spin_gets,wait_time from v$latch_children where addr=lpad(upper('8353a258'),'16','0')
ADDR NAME LEVEL# LATCH# GETS MISSES SLEEPS IMMEDIATE_GETS IMMEDIATE_MISSES WAITERS_WOKEN WAITS_HOLDING_LATCH SPIN_GETS WAIT_TIME
---------------- ---------------------------------------- ---------- ---------- ---------- ---------- ---------- -------------- ---------------- ------------- ------------------- ---------- ----------
000000008353A258 simulator hash latch 7 186 72792640 0 0 0 0 0 0 0 0
> select addr,name,level#,latch#,gets,misses,sleeps,immediate_gets,immediate_misses,waiters_woken,waits_holding_latch,spin_gets,wait_time from v$latch_children where addr=lpad(upper('844ed538'),'16','0')
ADDR NAME LEVEL# LATCH# GETS MISSES SLEEPS IMMEDIATE_GETS IMMEDIATE_MISSES WAITERS_WOKEN WAITS_HOLDING_LATCH SPIN_GETS WAIT_TIME
---------------- ---------------------------------------- ---------- ---------- ---------- ---------- ---------- -------------- ---------------- ------------- ------------------- ---------- ----------
00000000844ED538 simulator lru latch 6 185 563 1 0 72795249 3207148 0 0 1 0
--//我估計跟一些引數有關:
kslgetl 844ed538, 0, 49, 2062
kslgetl 8353a258, 1, 16777771, 2053
--//我猜測0表示no willing等待. 1表示willing等待.
--//我最後猜測也許正是11g下程式碼改動使用ksl_get_shared_latch,多了1次kslgetl呼叫,使用導致11g下每次執行多了2次times syscall,
--//可以講11g下唯一索引掃描是一個退步.
--//至於為什麼沒有阻塞看不到cbc latch獲取和釋放,我給再探究看看...
4.我加入1個欄位看看:
drop table t purge ;
create table t as select rownum id,'test' name from dual ;
create unique index pk_t on t(id);
alter table t modify id not null ;
$ cat z1.txt
set verify off
host sleep $(echo &&3/50 | bc -l )
variable vmethod varchar2(20);
exec :vmethod := '&&2';
insert into job_times values ( sys_context ('userenv', 'sid') ,dbms_utility.get_time ,:vmethod) ;
commit ;
declare
v_id number;
v_d date;
v_name varchar2(4) ;
begin
for i in 1 .. &&1 loop
select /*+ &&3 */ name into v_name from t where id=1 ;
end loop;
end ;
/
update job_times set time_ela = dbms_utility.get_time - time_ela where sid=sys_context ('userenv', 'sid') and method=:vmethod;
commit;
quit
--//重複測試:
--//11g:
SCOTT@book> Select method,count(*),round(avg(TIME_ELA),0),sum(TIME_ELA) from job_times group by method order by 3 ;
METHOD COUNT(*) ROUND(AVG(TIME_ELA),0) SUM(TIME_ELA)
-------------------- ---------- ---------------------- -------------
id=unindex_name 1 2135 2135
id=unindex 1 2723 2723
--//10g:
SCOTT@test> select method,count(*),round(avg(TIME_ELA),0),sum(TIME_ELA) from job_times group by method order by 3 ;
METHOD COUNT(*) ROUND(AVG(TIME_ELA),0) SUM(TIME_ELA)
-------------------- ---------- ---------------------- -------------
id=unindex_name 1 1359 1359
id=unindex 1 1591 1591
--//真心搞不懂,回表反而更快一些.oracle許多東西真心搞不懂....
--//感覺如果訪問資料塊快取資料塊,沒有阻塞無需要獲取cbc latch嗎?
5.附上gdb指令碼:
--//11g版本:
$ cat latch11g.gdb
break kslgetl
commands
silent
printf "kslgetl %x, %d, %d, %d\n", $rdi, $rsi, $rdx, $rcx
c
end
break kslges
commands
silent
printf "kslges %x, %d, %d, %d\n", $rdi, $rsi, $rdx, $rcx
c
end
break skgpwwait
commands
silent
printf "skgpwwait %d, %d, %d, %d\n", $rdi, $rsi, $rdx, $rcx
c
end
break sskgpwwait
commands
silent
printf "sskgpwwait %d, %d, %d, %d\n", $rdi, $rsi, $rdx, $rcx
c
end
break semop
commands
silent
printf "semop %d, %d, %d, %d\n", $rdi, $rsi, $rdx, $rcx
c
end
#break *0x93f9ddc
# commands
# silent
# printf " spin count loop: %d %d %x\n", $rax,$rcx,$rip
# c
# end
##
break kslgetsl_w
commands
silent
printf "kslgetsl_w laddr:%x, willing:%d, where:%d, why:%d, mode:%d\n", $rdi, $rsi, $rdx, $rcx, $r8
c
end
break ksl_get_shared_latch
commands
silent
printf "ksl_get_shared_latch laddr:%x, willing:%d, where:%d, why:%d, mode:%d\n", $rdi, $rsi, $rdx, $rcx, $r8
c
end
break kslgess
commands
silent
printf "kslgess %x, %d, %d, %d\n", $rdi, $rsi, $rdx, $rcx
c
end
break kslskgs
commands
silent
printf "kslskgs %x, %d, %d, %d\n", $rdi, $rsi, $rdx, $rcx
c
end
break kslfre
commands
silent
printf "kslfre %x, %d, %d, %d\n", $rdi, $rsi, $rdx, $rcx
c
end
#break *0xa875be
# commands
# silent
# printf " spin count loop: %d %x\n", $r13,$rip
# c
# end
--//10g版本:
$ cat latch10g.gdb
break kslgetl
commands
silent
printf "kslgetl %x, %d, %d, %d\n", $rdi, $rsi, $rdx, $rcx
c
end
break kslges
commands
silent
printf "kslges %x, %d, %d, %d\n", $rdi, $rsi, $rdx, $rcx
c
end
break skgpwwait
commands
silent
printf "skgpwwait %d, %d, %d, %d\n", $rdi, $rsi, $rdx, $rcx
c
end
break sskgpwwait
commands
silent
printf "sskgpwwait %d, %d, %d, %d\n", $rdi, $rsi, $rdx, $rcx
c
end
break semop
commands
silent
printf "semop %d, %d, %d, %d\n", $rdi, $rsi, $rdx, $rcx
c
end
#break *0x93f9ddc
# commands
# silent
# printf " spin count loop: %d %d %x\n", $rax,$rcx,$rip
# c
# end
##
break kslgetsl
commands
silent
printf "kslgetsl laddr:%x, willing:%d, where:%d, why:%d, mode:%d\n", $rdi, $rsi, $rdx, $rcx, $r8
c
end
#break ksl_get_shared_latch
# commands
# silent
# printf "ksl_get_shared_latch laddr:%x, willing:%d, where:%d, why:%d, mode:%d\n", $rdi, $rsi, $rdx, $rcx, $r8
# c
# end
break kslgess
commands
silent
printf "kslgess %x, %d, %d, %d\n", $rdi, $rsi, $rdx, $rcx
c
end
break kslskgs
commands
silent
printf "kslskgs %x, %d, %d, %d\n", $rdi, $rsi, $rdx, $rcx
c
end
#break *0xa875be
# commands
# silent
# printf " spin count loop: %d %x\n", $r13,$rip
# c
# end
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-2642222/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [20190401]那個更快的疑問.txt
- [20191210]降序索引疑問3.txt索引
- [20220406]使用那個shared pool latch的疑問1.txt
- [20220413]shared pool latch與使用sga heap的疑問3.txt
- [20190219]那個更快(11g).txt
- [20190215]那個更快(10g).txt
- 我的疑問
- MySQL關於資料字典的一個疑問MySql
- locust 使用的疑問
- 有些疑問
- 面試官常問的Nginx的那幾個問題?面試Nginx
- 打造企業級pipeline服務的18個疑問
- HashMap中的hash演算法中的幾個疑問HashMap演算法
- Python 疑難問題:[] 與 list() 哪個快?Python
- pycharm 小疑問PyCharm
- 【疑問】記錄
- 關於 dingo API 的疑問GoAPI
- [20231024]共享伺服器的問題3.txt伺服器
- 做學問要在不疑之處有疑
- Android 編譯打包的那些疑問Android編譯
- 通透,23 個問題 TCP 疑難雜症全解析TCP
- [20181124]關於降序索引問題3.txt索引
- 帶著疑問看故事
- 面試疑難問題面試
- [20191209]降序索引疑問.txt索引
- [20180713]關於hash join 測試中一個疑問.txt
- 【疑難系列】 一個看起來是資料庫死鎖的問題資料庫
- Vue學習遇到疑問的總結Vue
- RESTful設計中的常見疑問REST
- java——ArrayList中contains()方法中的疑問JavaAI
- [20190423]oradebug peek測試指令碼.txt指令碼
- [20190110]rlwrap sqlplus tee相關問題3.txtSQL
- [20220308]查詢x$ksmmem遇到的疑問.txt
- [20190510]rman備份的疑問8.txt
- [20190510]rman備份的疑問7.txt
- [20190509]rman備份的疑問5.txt
- Solidity學習疑問總結Solid
- [20190411]linux stat 命令疑問.txtLinux