这个是从我的outlook里拷贝出来的…… 当时也不知道咋的了 搜狗拼音打出来的字儿都是繁体……
假設我們需要執行一個batch job 並且不返回任何結果,那麼在database 本地服務器上執行 和在遠端執行 效率會有什麽差別嗎?
乍一聽起來 這似乎是個顯而易見的答案,肯定是一樣的。
實際上 這關乎到client plantform. 和client libraries。
做個試驗:
@lotslios 只是製造大量邏輯讀的腳本而已。
Using Windows sqlplus client (11.1.0.6):
SQL> @lotslios 10000
COUNT(*)
----------
10000
Elapsed: 00:00:29.28
SQL>
Using Linux sqlplus client (11.1.0.6):
SQL> @lotslios 10000
COUNT(*)
----------
10000
Elapsed: 00:00:27.24
SQL>
( 29.28 / 27.24 ) - 1 = ~7.5%
那麼如何檢查這些差異發生在何處呢? 首先介紹給大家一下思路
1.利用snapper 檢測這些session wait event profile到底在DB的消耗上有什麽不同(實際上差不多。都是單顆CPU 100%)
2.利用snapper 檢測這些session 在資源上消耗有何不同。(還是沒啥不同)
3.使用Strace ,Dtrace ,truss ,OProfiler 等其他debug技術來查看操作系統level的問題。
This is what the lotslios.sql generated when executed from Linux sqlplus:
solaris02$ truss -cp 18284
^C
syscall seconds calls errors
read .000 2
write .000 2
times .000 27
yield .000 159
-------- ------ ----
sys totals: .001 190 0
usr time: 27.191
elapsed: 31.080
This is what the lotslios.sql executed by Windows sqlplus generated:
solaris02$ truss -cp 19200
^C
syscall seconds calls errors
read .000 2
write .000 2
times .000 45
yield .000 196
pollsys 5.608 1355248
-------- ------ ----
sys totals: 5.610 1355493 0
usr time: 33.505
elapsed: 80.360
solaris02$
##strace 方式同上。但是strace 的实现方式灰常差劲,getrusage 在执行100次SQL的时候 getruage使用达到了600次。消耗非常惊人。本来跑10秒的SQL 在进行strace时可能几分钟都跑不出来。
那么pollsys 是用来做什么的呢?
我们可以使用truss 来确保使用pollsys 方法时来讲进程挂起:
truss -tpollsys -Tpollsys -p 19200
pollsys(0xFFFFFD7FFFDFB4F8, 1, 0xFFFFFD7FFFDFB4B0, 0x00000000) = 0
solaris02$
接下来 使用pstack 来检查进程做了些什么
solaris02$ pstack 19200
19200: oracleSOL10G (LOCAL=NO)
fffffd7ffdd52caa pollsys (fffffd7fffdfb4f8, 1, fffffd7fffdfb4b0, 0)
fffffd7ffdcf9dc2 poll () + 52
000000000508d37b sntpoltsts () + 12b
000000000507bc1b snttmoredata () + 2b
0000000004f7bcdf nsmore2recv () + 25f
0000000004f9a777 nioqts () + c7
0000000003706bb0 kdst_fetch () + 4e0
000000000375d14b kdstf0100101km () + 22b
00000000036f9dba kdsttgr () + 68a
00000000033c66bc qertbFetch () + 2ac
00000000033bebb3 qerjotFetch () + b3
000000000340edfc qercoFetch () + dc
0000000003461963 qergsFetch () + 723
0000000002932e9d opifch2 () + a0d
00000000028cf6cb kpoal8 () + e3b
0000000000e97c6c opiodr () + 41c
0000000003d9f6da ttcpip () + 46a
0000000000e939d3 opitsk () + 503
0000000000e96f18 opiino () + 3a8
0000000000e97c6c opiodr () + 41c
0000000000e924d1 opidrv () + 2f1
0000000000e8f90b sou2o () + 5b
0000000000e552e4 opimai_real () + 84
0000000000e551b4 main () + 64
0000000000e54ffc ???????? ()
原来非SNTT 开头的 应该是system network transport TCP?是用来检查是否有more data from network?
而snttmoredata call 了nsmore2recv 那么这个东西应该就是用来检查是否有moredata的了。
我想我们已经知道了 在两台server上执行有什么不同了。
实际上这是因为两种连接不同方式导致的 因为oracle 的client 往往效果都是 直到执行完成之前不反回任何结果 所以假设用户cancel 怎么办?那么就需要有个程序来反复检查 用户是否有call cancel这样的命令,这就是poll 这个方法需要做的事情(这个方法叫做 in-band break),那么同样的 如果这种检查过多 就会造成性能下降,而oracle在SQLNET.ORA 中也准备了这样的参数
break_poll_skip 默认是3 这意味着 每3次 pollsys()会有1次被执行
solaris02$ echo break_poll_skip=10 > $ORACLE_HOME/network/admin/sqlnet.ora
solaris02$
solaris02$
solaris02$ truss -cp 3316
^C
syscall seconds calls errors
read .000 2
write .000 2
times .000 33
yield .000 226
pollsys 1.726 406574
-------- ------ ----
sys totals: 1.727 406837 0
usr time: 29.526
elapsed: 48.530
看 时间被大大缩短了 只有1/10被执行了.
##pollsys()在linux上为poll()
Thanks.
---------------------------------------
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/21818314/viewspace-693210/,如需转载,请注明出处,否则将追究法律责任。