[20190215]那個更快(10g).txt
[20190215]那個更快(10g).txt
--//昨天測試11g Query Result Cache RC Latches時,連結http://blog.itpub.net/267265/viewspace-2632907/
--//有網友指出測試有問題,建立索引唯一,並不會導致select count(*) from t,選擇索引執行.實際上執行計劃還是全表掃描.
--//不過我後面的測試還是讓我有點吃驚....設定not null反而更慢..
--//在10g下重複測試看看.
1.環境:
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
create table t as select rownum id from dual ;
create unique index pk_t on t(id);
--//分析表略.
--//多個會話同時併發執行如下語句.
--//方式一:注這個時候索引沒用,因為id可以為null.
select count(*) from t;
--//方式二:
--//加入約束:alter table t modify (id not null);也就是使用索引
alter table t modify (id not null);
select count(*) from t;
--//方式三(索引唯一):
select count(*) from t where id=1;
--//方式四:(索引不唯一)
drop index pk_t;
create index pk_t on t(id);
select count(*) from t where id=1;
--//大家認為那個更快完成或者講花的時間更少?透過測試說明問題.
2.建立測試環境:
create table job_times (sid number, time_ela number,method varchar2(20));
CREATE OR REPLACE PROCEDURE do_work
(
p_iterations IN NUMBER
,p_method IN VARCHAR2
)
IS
l_rowid ROWID;
v_t NUMBER;
BEGIN
INSERT INTO job_times VALUES ( SYS_CONTEXT ('userenv', 'sid') ,DBMS_UTILITY.get_time ,p_method) RETURNING ROWID INTO l_rowid;
FOR i IN 1 .. p_iterations
LOOP
SELECT COUNT (*) INTO v_t FROM t;
END LOOP;
UPDATE job_times SET time_ela = DBMS_UTILITY.get_time - time_ela WHERE ROWID = l_rowid;
COMMIT;
END;
/
CREATE OR REPLACE PROCEDURE do_work1
(
p_iterations IN NUMBER
,p_method IN VARCHAR2
)
IS
l_rowid ROWID;
v_t NUMBER;
BEGIN
INSERT INTO job_times VALUES ( SYS_CONTEXT ('userenv', 'sid') ,DBMS_UTILITY.get_time ,p_method) RETURNING ROWID INTO l_rowid;
FOR i IN 1 .. p_iterations
LOOP
SELECT COUNT (*) INTO v_t FROM t where id=1;
END LOOP;
UPDATE job_times SET time_ela = DBMS_UTILITY.get_time - time_ela WHERE ROWID = l_rowid;
COMMIT;
END;
/
3.測試:
--//測試指令碼如下,10g不支援result cache.
--//執行指令碼如下:注一定要等50個會話執行完成在回車,進行下一項測試.
--//可以開啟另外的會話執行select method,count(*),avg(TIME_ELA),sum(TIME_ELA) from job_times group by method order by 3 ;
--//確定測試是否完成.
$ cat bb.txt
delete from job_times;
commit ;
drop table t purge;
create table t as select rownum id from dual ;
execute sys.dbms_stats.gather_table_stats ( OwnName => user,TabName => 't',Estimate_Percent => NULL,Method_Opt => 'FOR ALL COLUMNS SIZE 1 ',Cascade => True ,No_Invalidate => false);
hos seq &&1 | xargs -I{} echo "sqlplus -s -l scott/&&2 <<< \"execute do_work(1e6,'null')\" & " | bash > /dev/null
host read -p 'wait finish...'
create unique index pk_t on t(id);
alter table t modify (id not null);
host seq &&1 | xargs -I{} echo "sqlplus -s -l scott/&&2 <<< \"execute do_work(1e6,'notnull')\" & " | bash > /dev/null
host read -p 'wait finish...'
host seq &&1 | xargs -I{} echo "sqlplus -s -l scott/&&2 <<< \"execute do_work1(1e6,'id=1_unique_index')\" & " | bash > /dev/null
host read -p 'wait finish...'
drop index pk_t ;
create index pk_t on t(id);
host seq &&1 | xargs -I{} echo "sqlplus -s -l scott/&&2 <<< \"execute do_work1(1e6,'id=1_index')\" & " | bash > /dev/null
host read -p 'wait finish...'
--//注:引數1 啟動連線數, 引數2 scott的密碼.
--//說明:
--//第1次,id null,全表掃描T,邏輯讀3個.主要等待事件是latch: cache buffers chains.
--//第2次:id not null,建立唯一索引.執行計劃走INDEX FULL SCAN,邏輯讀1.主要等待事件是latch: cache buffers chains.
--//第3次:查詢增加where id=1,執行計劃走 INDEX UNIQUE SCAN,邏輯讀1,主要等待事件是cursor: pin S .
--//第4次:查詢增加where id=1,由於索引不唯一,執行計劃走INDEX RANGE SCAN,邏輯讀1,主要等待事件是latch: cache buffers chains.
--//測試結果如下:
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=1_unique_index 50 4789 239432
notnull 50 34493 1724641
id=1_index 50 34568 1728409
null 50 38319 1915970
--//第2次測試結果:
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=1_unique_index 50 4864 243192
notnull 50 34134 1706713
id=1_index 50 34703 1735173
null 50 37234 1861717
--//可以發現10g下not null 與id=1 索引非唯一的情況測試很接近,這個很好理解邏輯讀都是1.主要等待事件都是latch: cache buffers chains.
--//而null的情況全表掃描的邏輯讀是3,這樣發生cbc latch的等待事件更加嚴重,這樣比邏輯讀1的情況下更加慢一些。
--//而id=1 並且使用唯一索引的情況下,oracle對這樣情況進行特殊最佳化,僅僅有1次cbc latch拴鎖。主要等待事件是cursor: pin S .
--//順便貼上看等待事件的指令碼(wait10g.sql).
select p1raw,p2raw,p3raw,p1,p2,p3,sid,serial#,seq#,event,state,wait_time,seconds_in_wait from v$session where wait_class<>'Idle'
and sid not in (select sid from v$mystat where rownum=1)
order by event ;
--//而11g下呢? 貼出11.2.0.4下的測試結果如下:
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)
-------------------- ------------- ---------------------- -------------
result_cache 50 8805 440251
id=1_unique_index 50 9505 475229
null 50 10841 542033
notnull 50 28310 1415522
id=1_index 50 29531 1476574
--//你可以發現與11g很大不同,10g下id 欄位 null 與id 欄位 not null差別不大.兩者都後大量出現latch: cache buffers chains.
--//而id=1,如果看vage的書就明白,僅僅出現1次cbc latch.而且非常快.
--//實際上11g的環境與10g環境伺服器配置基本一樣.感覺11g在latch: cache buffers chains做了一些改進,全表掃描很奇怪看不到
--//cbc latch的等待事件.但是11g雖然減少cbc latch相關等待事件時間,但是透過索引唯一讀取記錄的需要時間是增加的(對比上面10g的
--//測試結果),其中一些細節我自己也講不好,就不說明了.
--//另外11g下id not null,建立唯一索引.執行計劃走INDEX FULL SCAN,邏輯讀1.主要等待事件是latch: cache buffers chains.
--//這是11g下有如下兩種情況能看到cbc latch的情況(notnull,id=1_index),儘管邏輯讀為1,你可以發現是最慢的,而且時間比null
--//做全表掃描(邏輯讀3)的情況下還慢1倍還多。
--//順便貼上看等待事件的指令碼(wait.sql).
select p1raw,p2raw,p3raw,p1,p2,p3,sid,serial#,seq#,event,status,state,wait_time_micro,seconds_in_wait,wait_class
from v$session where ( wait_class<>'Idle' or (status='ACTIVE' and STATE='WAITED KNOWN TIME'))
and sid not in (select sid from v$mystat where rownum=1)
order by event ;
--//補充11g的測試指令碼如下,加入了將表設定為result_cahe=force的情況。
$ cat bb.txt
delete from job_times;
commit ;
drop table t purge;
create table t as select rownum id from dual ;
execute sys.dbms_stats.gather_table_stats ( OwnName => user,TabName => 't',Estimate_Percent => NULL,Method_Opt => 'FOR ALL COLUMNS SIZE 1 ',Cascade => True ,No_Invalidate => false);
hos seq &&1 | xargs -I{} echo "sqlplus -s -l scott/&&2 <<< \"execute do_work(1e6,'null')\" & " | bash > /dev/null
host read -p 'wait finish...'
create unique index pk_t on t(id);
alter table t modify (id not null);
host seq &&1 | xargs -I{} echo "sqlplus -s -l scott/&&2 <<< \"execute do_work(1e6,'notnull')\" & " | bash > /dev/null
host read -p 'wait finish...'
host seq &&1 | xargs -I{} echo "sqlplus -s -l scott/&&2 <<< \"execute do_work1(1e6,'id=1_unique_index')\" & " | bash > /dev/null
host read -p 'wait finish...'
drop index pk_t ;
create index pk_t on t(id);
host seq &&1 | xargs -I{} echo "sqlplus -s -l scott/&&2 <<< \"execute do_work1(1e6,'id=1_index')\" & " | bash > /dev/null
host read -p 'wait finish...'
alter table t result_cache (mode force);
host seq &&1| xargs -I{} echo "sqlplus -s -l scott/&&2 <<< \"execute do_work(1e6,'result_cache')\" & " | bash > /dev/null
host read -p 'wait finish...'
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-2636321/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [20190401]那個更快的疑問.txt
- [20190219]那個更快(11g).txt
- [20190423]那個更快的疑問3.txt
- [20190215]sqlplus set arraysize.txtSQL
- [20190530]DISABLE TABLE LOCK(10g).txt
- [20210708]使用那個shared pool latch.txt
- [20180412]logminer使用問題(10g).txt
- [20210803]使用那個shared pool latch(補充).txt
- [20201113]測試CURSOR_SPACE_FOR_TIME(10g).txt
- [20190415]10g下那些latch是共享的.txt
- 面試題-python 如何讀取一個大於 10G 的txt檔案?面試題Python
- [20220406]使用那個shared pool latch的疑問1.txt
- [20181029]避免表示式在sql語句中(10g).txtSQL
- [20181105]ORA-00600[4000] 模擬故障(10g).txt
- [20190102]關於字串的分配問題(10g).txt字串
- [20201116]測試CURSOR_SPACE_FOR_TIME(10g)(補充).txt
- [20180625]10g下查詢條件rownum = 0.txt
- [20180828]關於引數cursor_space_for_time(10g).txt
- 每週分享第 13 期(20190215)
- [20181030]避免表示式在sql語句中(10g)(補充).txtSQL
- 10g sqlplus的一個bugSQL
- [20181022]lob欄位的lobid來之那裡.txt
- 10g RAC on AIXAI
- Hibernate Validator、Regex 和手動驗證:哪個更快?
- 11個點讓你的Spring Boot啟動更快Spring Boot
- 21 個VSCode 快捷鍵,讓程式碼更快,更有趣VSCode
- SpringAOP中JDK和CGLib動態代理哪個更快?SpringJDKCGLib
- 殺死那個遊戲公司遊戲
- 回憶裡的那個人……
- python多個txt合併Python
- oracle 10g flashback databaseOracle 10gDatabase
- 10G DG SWITCH OVER
- 7個讓網站更快的網頁設計技巧網站網頁
- WI-FI 6與5G相比哪個更快?
- [20190201]測試服務名支援靜態和動態註冊的情況下優先選擇那個.txt
- 如何對比多個庫,看看那個最靠譜
- 使用那個銀行購匯方便
- 揪出那個無主鍵的表