[20231013]為什麼刷新緩存後輸出記錄順序發生變化3.txt

来源:https://www.cnblogs.com/lfree/archive/2023/10/23/17783558.html
-Advertisement-
Play Games

更多技術交流、求職機會,歡迎關註位元組跳動數據平臺微信公眾號,回覆【1】進入官方交流群 近年來,隨著消費者的心理需求逐步趨向於精神層面、科技的迭代迅速以及市場環境的複雜性逐步上升,我國的廣告行業逐步展開新的投放模式。但流量成本高,企業試錯成本高昂,如何在控製成本的同時實現廣告投放效益最大化,成為廣告投 ...


[20231013]為什麼刷新緩存後輸出記錄順序發生變化3.txt

--//當年提的問題,鏈接http://blog.itpub.net/267265/viewspace-2763181/=> [20210316]為什麼刷新緩存後輸出記錄順序發生變化.txt,
--//正好別人問我,順便我重覆看了一下,順便解答這個問題,實際上也許解答不對,許多行為我僅僅是猜測。
--//實際上這個問題在於oracle 在索引範圍掃描時如果數據塊不在緩存,有可能採用db file parallel read的方式讀取數據塊。
--//最直觀的表現在執行計划上出現TABLE ACCESS BY INDEX ROWID BATCHED。
--//這個特性僅僅出現在12c以後,另外windows下我的測試有點奇怪,大家可以自行測試。我不再說明,我的測試在linux環境進行。

1.環境:
[email protected]:1521/orcl> @ ver1
[email protected]:1521/orcl> @ pr
==============================
PORT_STRING                   : x86_64/Linux 2.4.xx
VERSION                       : 18.0.0.0.0
BANNER                        : Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production
BANNER_FULL                   : Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production
Version 18.3.0.0.0
BANNER_LEGACY                 : Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production
CON_ID                        : 0
PL/SQL procedure successfully completed.

2.建立測試例子:
[email protected]:1521/orcl> create table t  pctfree 99 as select level id, lpad(level, 3500, '0') vc from dual connect by level <= 500 order by dbms_random.random;
Table created.
--//建立的表非常特殊1塊1條記錄,這樣便於後面的分析。

[email protected]:1521/orcl> create index i_t_id on t(id) ;
Index created.

[email protected]:1521/orcl> exec dbms_stats.gather_table_stats(null, 'T', cascade=>true);
PL/SQL procedure successfully completed.

3.測試:
TTT@orcl> show rowprefetch array
rowprefetch 1
arraysize 200

TTT@orcl> select /*+ index(t) */ id,substr(vc,3498,3),rowid from  t where id between 1 and 10;
        ID SUBSTR ROWID
---------- ------ ------------------
         1 001    AABnNmAAMAAC/JYAAA
         2 002    AABnNmAAMAAC/IqAAA
         3 003    AABnNmAAMAAC+78AAA
         4 004    AABnNmAAMAAC/KSAAA
         5 005    AABnNmAAMAAC+7pAAA
         6 006    AABnNmAAMAAC/L2AAA
         7 007    AABnNmAAMAAC/K8AAA
         8 008    AABnNmAAMAAC/IgAAA
         9 009    AABnNmAAMAAC/G5AAA
        10 010    AABnNmAAMAAC/J7AAA
10 rows selected.
--//執行計劃選擇索引範圍掃描與全部數據塊在緩存的情況下按照id順序輸出,如果不出現上面的執行輸出,你可以再執行1次看看是否出
--//現.

TTT@orcl> alter system flush buffer_cache;
System altered.

TTT@orcl> select /*+ index(t) */ id,substr(vc,3498,3),rowid from  t where rowid='AABnNmAAMAAC/L2AAA';
        ID SUBSTR ROWID
---------- ------ ------------------
         6 006    AABnNmAAMAAC/L2AAA

TTT@orcl> select /*+ index(t) */ id,substr(vc,3498,3),rowid from  t where id between 1 and 10;
        ID SUBSTR ROWID
---------- ------ ------------------
         1 001    AABnNmAAMAAC/JYAAA
         2 002    AABnNmAAMAAC/IqAAA
         3 003    AABnNmAAMAAC+78AAA
         6 006    AABnNmAAMAAC/L2AAA
        10 010    AABnNmAAMAAC/J7AAA
         4 004    AABnNmAAMAAC/KSAAA
         5 005    AABnNmAAMAAC+7pAAA
         7 007    AABnNmAAMAAC/K8AAA
         8 008    AABnNmAAMAAC/IgAAA
         9 009    AABnNmAAMAAC/G5AAA
10 rows selected.
--//如果緩存id=6的數據塊,跑到前面去好理解,因為其它數據塊不再緩存裡面,db file parallel read操作對於上面的情況,
--//我的理解先通過rowid確定那些數據塊需要讀取,然後按照文件號以及數據塊號排序,從小到大讀取.id=6數據已經在數據緩存,
--//這樣讀取操作已經進入fetch池(這個是我亂想的),優先輸出.
--//你還可以看到id=2,3的記錄在id=6的前面,為什麼呢?實際上當數據不在緩存時並不是馬上採用db file parallel read操作,
--//而是先採用db file sequential read(當然在數據緩存情況除外)2次,再有讀取操作才有可能採用db file parallel read.
--//註:有1個特例,如果要訪問的數據塊是連續的讀取出現的等待事件是db file scattered read.
--//你可以建表時order by 1測試的等待事件是db file scattered read.
--//問題在於為什麼刷新數據緩存後,id=10的記錄顯示在前面.

4.繼續測試:
TTT@orcl> alter system flush buffer_cache;
System altered.

TTT@orcl> select /*+ index(t) */ id,substr(vc,3498,3),rowid from  t where rowid='AABnNmAAMAAC/IqAAA';
        ID SUBSTR ROWID
---------- ------ ------------------
         2 002    AABnNmAAMAAC/IqAAA

TTT@orcl> select /*+ index(t) */ id,substr(vc,3498,3),rowid from  t where rowid='AABnNmAAMAAC+78AAA';
        ID SUBSTR ROWID
---------- ------ ------------------
         3 003    AABnNmAAMAAC+78AAA

TTT@orcl> select /*+ index(t) */ id,substr(vc,3498,3),rowid from  t where rowid='AABnNmAAMAAC/L2AAA';
        ID SUBSTR ROWID
---------- ------ ------------------
         6 006    AABnNmAAMAAC/L2AAA
--//緩存id=2,3,6的數據塊.        

TTT@orcl> select /*+ index(t) */ id,substr(vc,3498,3),rowid from  t where id between 1 and 10;
        ID SUBSTR ROWID
---------- ------ ------------------
         1 001    AABnNmAAMAAC/JYAAA
         2 002    AABnNmAAMAAC/IqAAA
         3 003    AABnNmAAMAAC+78AAA
         4 004    AABnNmAAMAAC/KSAAA
         6 006    AABnNmAAMAAC/L2AAA
        10 010    AABnNmAAMAAC/J7AAA
         5 005    AABnNmAAMAAC+7pAAA
         7 007    AABnNmAAMAAC/K8AAA
         8 008    AABnNmAAMAAC/IgAAA
         9 009    AABnNmAAMAAC/G5AAA
10 rows selected.
--//總之是先出現1,2次db file sequential read,才會有可能採用db file parallel read操作.

TTT@orcl> alter system flush buffer_cache;
System altered.

TTT@orcl> select /*+ index(t) */ id,substr(vc,3498,3),rowid from  t where rowid='AABnNmAAMAAC/JYAAA';
        ID SUBSTR ROWID
---------- ------ ------------------
         1 001    AABnNmAAMAAC/JYAAA

TTT@orcl> select /*+ index(t) */ id,substr(vc,3498,3),rowid from  t where rowid='AABnNmAAMAAC/IqAAA';
        ID SUBSTR ROWID
---------- ------ ------------------
         2 002    AABnNmAAMAAC/IqAAA

TTT@orcl>  select /*+ index(t) */ id,substr(vc,3498,3),rowid from  t where rowid='AABnNmAAMAAC+78AAA';
        ID SUBSTR ROWID
---------- ------ ------------------
         3 003    AABnNmAAMAAC+78AAA
--//緩存id=1,2,3的數據塊.

TTT@orcl> select /*+ index(t) */ id,substr(vc,3498,3),rowid from  t where id between 1 and 10;
        ID SUBSTR ROWID
---------- ------ ------------------
         1 001    AABnNmAAMAAC/JYAAA
         2 002    AABnNmAAMAAC/IqAAA
         3 003    AABnNmAAMAAC+78AAA
         4 004    AABnNmAAMAAC/KSAAA
        10 010    AABnNmAAMAAC/J7AAA
         5 005    AABnNmAAMAAC+7pAAA
         6 006    AABnNmAAMAAC/L2AAA
         7 007    AABnNmAAMAAC/K8AAA
         8 008    AABnNmAAMAAC/IgAAA
         9 009    AABnNmAAMAAC/G5AAA
10 rows selected.
--//但是還是無法理解為什麼這樣的情況下id=10優先輸出.

5.繼續分析:
TTT@orcl> update t set id=10 where id=11;
1 row updated.

TTT@orcl> commit ;
Commit complete.
--//修改id=11為id=10,這樣輸出多一條記錄.

TTT@orcl> alter system flush buffer_cache;
System altered.

TTT@orcl> select /*+ index(t) */ id,substr(vc,3498,3),rowid from  t where id between 1 and 10;
        ID SUBSTR ROWID
---------- ------ ------------------
         1 001    AABnNmAAMAAC/JYAAA
         2 002    AABnNmAAMAAC/IqAAA
         3 003    AABnNmAAMAAC+78AAA
        10 011    AABnNmAAMAAC/N/AAA
         4 004    AABnNmAAMAAC/KSAAA
         5 005    AABnNmAAMAAC+7pAAA
         6 006    AABnNmAAMAAC/L2AAA
         7 007    AABnNmAAMAAC/K8AAA
         8 008    AABnNmAAMAAC/IgAAA
         9 009    AABnNmAAMAAC/G5AAA
        10 010    AABnNmAAMAAC/J7AAA
11 rows selected.
--//在sqlplus下執行fetch的數量總是1,array,array,..,剩下的數據.
--//註:前面的1=rowprefetch,rowprefetch與array的關係有點複雜,我不建議設置rowprefetch>=arraysize的情況.
--//rowprefetch 的設置僅僅sqlplus 12c以上版本才能設置.

--//這樣看來id=10的優先輸出一定與db file parallel read操作有關.

6.做1次10046跟蹤:
TTT@orcl> alter system flush buffer_cache;
System altered.

TTT@orcl> alter session set events '10046 trace name context forever, level 12';
Session altered.

TTT@orcl> select /*+ index(t) */ id,substr(vc,3498,3),rowid from  t where id between 1 and 10;
        ID SUBSTR ROWID
---------- ------ ------------------
         1 001    AABnNmAAMAAC/JYAAA
         2 002    AABnNmAAMAAC/IqAAA
         3 003    AABnNmAAMAAC+78AAA
        10 011    AABnNmAAMAAC/N/AAA
         4 004    AABnNmAAMAAC/KSAAA
         5 005    AABnNmAAMAAC+7pAAA
         6 006    AABnNmAAMAAC/L2AAA
         7 007    AABnNmAAMAAC/K8AAA
         8 008    AABnNmAAMAAC/IgAAA
         9 009    AABnNmAAMAAC/G5AAA
        10 010    AABnNmAAMAAC/J7AAA
11 rows selected.

TTT@orcl> alter session set events '10046 trace name context off';
Session altered.

[email protected]:1521/orcl> @ oid 422758
owner object_name object_type        SUBOBJECT_NAME CREATED             LAST_DDL_TIME       status    DATA_OBJECT_ID  OBJECT_ID
----- ----------- ------------------ -------------- ------------------- ------------------- --------- -------------- ----------
TTT   T           TABLE                             2023-10-13 09:19:25 2023-10-13 09:19:46 VALID             422758     422758

[email protected]:1521/orcl> @ oid 422759
owner object_name object_type        SUBOBJECT_NAME CREATED             LAST_DDL_TIME       status    DATA_OBJECT_ID  OBJECT_ID
----- ----------- ------------------ -------------- ------------------- ------------------- --------- -------------- ----------
TTT   I_T_ID      INDEX                             2023-10-13 09:19:45 2023-10-13 09:19:45 VALID             422759     422759

$ egrep "db file|FETCH" /u01/app/oracle/diag/rdbms/orclcdb/orclcdb/trace/orclcdb_ora_28039.trc
WAIT #139969772337544: nam='db file sequential read' ela= 428 file#=41 block#=782811 blocks=1 obj#=422759 tim=11387992574423   --//索引root
WAIT #139969772337544: nam='db file sequential read' ela= 281 file#=41 block#=782812 blocks=1 obj#=422759 tim=11387992574858   --//索引葉子
WAIT #139969772337544: nam='db file sequential read' ela= 20377 file#=41 block#=782936 blocks=1 obj#=422758 tim=11387992595353 --//id=1
FETCH #139969772337544:c=1320,e=21673,p=3,cr=3,cu=0,mis=0,r=1,dep=0,og=1,plh=3446268138,tim=11387992595609
WAIT #139969772337544: nam='db file sequential read' ela= 3548 file#=41 block#=782890 blocks=1 obj#=422758 tim=11387992601138  --//id=2
WAIT #139969772337544: nam='db file sequential read' ela= 11913 file#=41 block#=782076 blocks=1 obj#=422758 tim=11387992613217 --//id=3
WAIT #139969772337544: nam='db file parallel read' ela= 31429 files=1 blocks=8 requests=8 obj#=422758 tim=11387992645691       --//id=4..10
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
FETCH #139969772337544:c=2076,e=48359,p=10,cr=11,cu=0,mis=0,r=10,dep=0,og=1,plh=3446268138,tim=11387992645894
--//註:db file parallel read 看到blocks=8,具體讀取那些塊,你可以使用strace -fp spid -e pread|pread64 跟蹤 確定。
--//我以前做過類似測試,不再贅述。

--//我當時做到這裡db file parallel read最大請求blocks的數量是127(註:這個很容易測試出來),而且還與arraysize參數有關。
--//oracle執行時先從索引收集rowid,確定那些文件與數據塊要讀取,按照文件號與塊號排序,抽取數據塊進入緩存後,按照索引的讀取順
--//序數據塊(不然不是這樣的順序輸出),當然已經在數據緩存的塊記錄優先填充.當讀取數量達到arraysize或者沒有剩餘記錄時輸出結
--//果,而最後1條記錄會優先輸出,這樣就會出現前面id=10優先輸出的情況.

--//註:解析的非常牽強,那位能給出更好更合理的解析。
--//會不會要判斷是否達到arraysize數量,我的sql語句沒有加入過濾,下個星期繼續測試看看。

--//設置arraysize=5看看.

TTT@orcl> set arraysize 5
TTT@orcl> alter system flush buffer_cache;
System altered.

TTT@orcl> select /*+ index(t) */ id,substr(vc,3498,3),rowid from  t where id between 1 and 10;
        ID SUBSTR ROWID
---------- ------ ------------------
         1 001    AABnNmAAMAAC/JYAAA
         2 002    AABnNmAAMAAC/IqAAA
         3 003    AABnNmAAMAAC+78AAA
         6 006    AABnNmAAMAAC/L2AAA
         4 004    AABnNmAAMAAC/KSAAA
         5 005    AABnNmAAMAAC+7pAAA
        10 011    AABnNmAAMAAC/N/AAA
         7 007    AABnNmAAMAAC/K8AAA
         8 008    AABnNmAAMAAC/IgAAA
         9 009    AABnNmAAMAAC/G5AAA
        10 010    AABnNmAAMAAC/J7AAA
11 rows selected.

--//如果數據全部在緩存輸出順序
1
2,3,4,5,6
7,8,9,10,10(vc=011)

--//全部不再緩存順序應該是
1
2,3,6,4,5
10(vc=011),7,8,9,10
--//與真實的測試結果能對上。

--//如果arraysize=4呢?
--//如果數據全部在緩存輸出順序
1
2,3,4,5
6,7,8,9
10,10(vc=011)

--//全部不再緩存順序應該是
1
2,3,5,4
9,6,7,8
10(vc=011),10
--//驗證我的判斷是否正確

TTT@orcl> set arraysize 4
TTT@orcl> alter system flush buffer_cache;
System altered.

TTT@orcl> select /*+ index(t) */ id,substr(vc,3498,3),rowid from  t where id between 1 and 10;
        ID SUBSTR ROWID
---------- ------ ------------------
         1 001    AABnNmAAMAAC/JYAAA
         2 002    AABnNmAAMAAC/IqAAA
         3 003    AABnNmAAMAAC+78AAA
         5 005    AABnNmAAMAAC+7pAAA
         4 004    AABnNmAAMAAC/KSAAA
         9 009    AABnNmAAMAAC/G5AAA
         6 006    AABnNmAAMAAC/L2AAA
         7 007    AABnNmAAMAAC/K8AAA
         8 008    AABnNmAAMAAC/IgAAA
        10 011    AABnNmAAMAAC/N/AAA
        10 010    AABnNmAAMAAC/J7AAA
11 rows selected.
--//你可以發現能與我的猜測對上.
--//10046跟蹤內容如下:
$ egrep "db file|FETCH" /u01/app/oracle/diag/rdbms/orclcdb/orclcdb/trace/orclcdb_ora_28039.trc
WAIT #139969774020880: nam='db file sequential read' ela= 341 file#=41 block#=782811 blocks=1 obj#=422759 tim=11389669160631
WAIT #139969774020880: nam='db file sequential read' ela= 220 file#=41 block#=782812 blocks=1 obj#=422759 tim=11389669160991
WAIT #139969774020880: nam='db file sequential read' ela= 389 file#=41 block#=782936 blocks=1 obj#=422758 tim=11389669161510
FETCH #139969774020880:c=880,e=1404,p=3,cr=3,cu=0,mis=0,r=1,dep=0,og=1,plh=3446268138,tim=11389669161591
WAIT #139969774020880: nam='db file sequential read' ela= 377 file#=41 block#=782890 blocks=1 obj#=422758 tim=11389669163820
WAIT #139969774020880: nam='db file sequential read' ela= 490 file#=41 block#=782076 blocks=1 obj#=422758 tim=11389669164442
WAIT #139969774020880: nam='db file parallel read' ela= 208 files=1 blocks=2 requests=2 obj#=422758 tim=11389669165139
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
FETCH #139969774020880:c=1088,e=1884,p=4,cr=5,cu=0,mis=0,r=4,dep=0,og=1,plh=3446268138,tim=11389669165249
WAIT #139969774020880: nam='db file parallel read' ela= 27 files=1 blocks=4 requests=4 obj#=422758 tim=11389669166538
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
FETCH #139969774020880:c=439,e=845,p=4,cr=5,cu=0,mis=0,r=4,dep=0,og=1,plh=3446268138,tim=11389669166657
WAIT #139969774020880: nam='db file parallel read' ela= 79 files=1 blocks=2 requests=2 obj#=422758 tim=11389669167635
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
FETCH #139969774020880:c=515,e=631,p=2,cr=3,cu=0,mis=0,r=2,dep=0,og=1,plh=3446268138,tim=11389669167746
--//sqlplus arraysize設置與db file parallel read的最大讀取塊數量有關.

7.總結:
--//實際上這些細節並不重要,說明幾點:
1.sqlplus arraysize設置與db file parallel read的最大讀取塊數量有關.
2.要排序輸出一定顯示加入order by操作.
3.我給再好好看看我以前的鏈接:[20200824]12c sqlplus rowprefetch arraysize 顯示行數量的關係.txt =>http://blog.itpub.net/267265/viewspace-2714661/
4.我前面的查詢沒有出現過濾,下個星期應該補充測試出現過濾的情況。

8.補充測試:

--//grant EXECUTE ON  dbms_lock to TTT;

CREATE OR REPLACE FUNCTION sleepT (seconds IN NUMBER)
   RETURN timestamp
AS
BEGIN
   --//sys.DBMS_LOCK.sleep (seconds);
   sys.DBMS_session.sleep (seconds);
   RETURN SYSTIMESTAMP-seconds/86400;
END;
/


$ cat aa.txt
set term off
set timing on
set arraysize &1
set rowprefetch &2
alter system flush buffer_cache;
alter session set events '10046 trace name context forever, level 12';
set term on
select /*+ index(t) */ id,substr(vc,3498,3),rowid,sleept(1) from t where id between 1 and 10;
set term off
alter session set events '10046 trace name context off';
set timing off
set term on
quit

$ cat /usr/local/bin/ts.awk
#! /bin/bash
awk '{ print strftime("[%Y-%m-%d %H:%M:%S]"), $0 }'

$ sqlplus -s -l ttt/oracle@orcl @ aa.txt 200 1 | ts.awk
[2023-10-16 08:39:46]
[2023-10-16 08:39:46]         ID SUBSTR ROWID              SLEEPT(1)
[2023-10-16 08:39:46] ---------- ------ ------------------ ------------------------------
[2023-10-16 08:39:46]          1 001    AABnNmAAMAAC/JYAAA 2023-10-16 08:39:35.000000000
[2023-10-16 08:39:46]          2 002    AABnNmAAMAAC/IqAAA 2023-10-16 08:39:36.000000000
[2023-10-16 08:39:46]          3 003    AABnNmAAMAAC+78AAA 2023-10-16 08:39:37.000000000
[2023-10-16 08:39:46]         10 011    AABnNmAAMAAC/N/AAA 2023-10-16 08:39:38.000000000
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[2023-10-16 08:39:46]          4 004    AABnNmAAMAAC/KSAAA 2023-10-16 08:39:39.000000000
[2023-10-16 08:39:46]          5 005    AABnNmAAMAAC+7pAAA 2023-10-16 08:39:40.000000000
[2023-10-16 08:39:46]          6 006    AABnNmAAMAAC/L2AAA 2023-10-16 08:39:41.000000000
[2023-10-16 08:39:46]          7 007    AABnNmAAMAAC/K8AAA 2023-10-16 08:39:42.000000000
[2023-10-16 08:39:46]          8 008    AABnNmAAMAAC/IgAAA 2023-10-16 08:39:43.000000000
[2023-10-16 08:39:46]          9 009    AABnNmAAMAAC/G5AAA 2023-10-16 08:39:44.000000000
[2023-10-16 08:39:46]         10 010    AABnNmAAMAAC/J7AAA 2023-10-16 08:39:45.000000000
[2023-10-16 08:39:46]
[2023-10-16 08:39:46] 11 rows selected.
[2023-10-16 08:39:46]
[2023-10-16 08:39:46] Elapsed: 00:00:11.09
--//顯示輸出有11秒間隔.
--//註意看sleept(1)列,顯示的時間順序增加的。

$ sqlplus -s -l ttt/oracle@orcl @ aa.txt 4 1 | ts.awk
[2023-10-19 10:04:26]
[2023-10-19 10:04:26]         ID SUBSTR ROWID              SLEEPT(1)
[2023-10-19 10:04:26] ---------- ------ ------------------ -----------------------------
[2023-10-19 10:04:26]          1 001    AABnNmAAMAAC/JYAAA 2023-10-19 10:04:21.000000000
[2023-10-19 10:04:26]          2 002    AABnNmAAMAAC/IqAAA 2023-10-19 10:04:22.000000000
[2023-10-19 10:04:26]          3 003    AABnNmAAMAAC+78AAA 2023-10-19 10:04:23.000000000
[2023-10-19 10:04:26]          5 005    AABnNmAAMAAC+7pAAA 2023-10-19 10:04:24.000000000
[2023-10-19 10:04:30]          4 004    AABnNmAAMAAC/KSAAA 2023-10-19 10:04:25.000000000
[2023-10-19 10:04:30]          9 009    AABnNmAAMAAC/G5AAA 2023-10-19 10:04:26.000000000
[2023-10-19 10:04:30]          6 006    AABnNmAAMAAC/L2AAA 2023-10-19 10:04:27.000000000
[2023-10-19 10:04:30]          7 007    AABnNmAAMAAC/K8AAA 2023-10-19 10:04:28.000000000
[2023-10-19 10:04:32]          8 008    AABnNmAAMAAC/IgAAA 2023-10-19 10:04:29.000000000
[2023-10-19 10:04:32]         10 011    AABnNmAAMAAC/N/AAA 2023-10-19 10:04:30.000000000
[2023-10-19 10:04:32]         10 010    AABnNmAAMAAC/J7AAA 2023-10-19 10:04:31.000000000
[2023-10-19 10:04:32]
[2023-10-19 10:04:32] 11 rows selected.
[2023-10-19 10:04:32]
[2023-10-19 10:04:32] Elapsed: 00:00:11.01
--//fetch的數量是 1,4,4,2.
--//而顯示的數量(看前面的時間)  4,4,3。
--//參考:[20200824]12c sqlplus rowprefetch arraysize 顯示行數量的關係.txt =>http://blog.itpub.net/267265/viewspace-2714661/

$ sqlplus -s -l ttt/oracle@orcl @ aa.txt 2 1 | ts.awk
[2023-10-19 10:03:24]
[2023-10-19 10:03:24]         ID SUBSTR ROWID              SLEEPT(1)
[2023-10-19 10:03:24] ---------- ------ ------------------ -----------------------------
[2023-10-19 10:03:24]          1 001    AABnNmAAMAAC/JYAAA 2023-10-19 10:03:21.000000000
[2023-10-19 10:03:24]          2 002    AABnNmAAMAAC/IqAAA 2023-10-19 10:03:22.000000000
[2023-10-19 10:03:26]          3 003    AABnNmAAMAAC+78AAA 2023-10-19 10:03:23.000000000
[2023-10-19 10:03:26]          4 004    AABnNmAAMAAC/KSAAA 2023-10-19 10:03:24.000000000
[2023-10-19 10:03:28]          5 005    AABnNmAAMAAC+7pAAA 2023-10-19 10:03:25.000000000
[2023-10-19 10:03:28]          7 007    AABnNmAAMAAC/K8AAA 2023-10-19 10:03:26.000000000
[2023-10-19 10:03:30]          6 006    AABnNmAAMAAC/L2AAA 2023-10-19 10:03:27.000000000
[2023-10-19 10:03:30]          9 009    AABnNmAAMAAC/G5AAA 2023-10-19 10:03:28.000000000
[2023-10-19 10:03:33]          8 008    AABnNmAAMAAC/IgAAA 2023-10-19 10:03:29.000000000
[2023-10-19 10:03:33]         10 011    AABnNmAAMAAC/N/AAA 2023-10-19 10:03:31.000000000
[2023-10-19 10:03:33]         10 010    AABnNmAAMAAC/J7AAA 2023-10-19 10:03:32.000000000
[2023-10-19 10:03:33]
[2023-10-19 10:03:33] 11 rows selected.
[2023-10-19 10:03:33]
[2023-10-19 10:03:33] Elapsed: 00:00:11.06
--//我不展開分析了。僅僅7,6 9,8 10(vc=011),10 輸出順序反了。

--//補充加入過濾的情況,還原id=11的記錄。
update t set id=11 where substr(vc,3498,3)='011';
commit ;

--//加入過濾條件:
$ cat ab.txt
set term off
set timing on
set arraysize &1
set rowprefetch &2
alter system flush buffer_cache;
alter session set events '10046 trace name context forever, level 12';
set term on
select /*+ index(t) */ id,substr(vc,3498,3),rowid,sleept(1) from t where id between 1 and 10 and substr(vc,3498,3)<>'005';
set term off
alter session set events '10046 trace name context off';
set timing off
set term on
quit

--//不輸出id =5的記錄。

$ sqlplus -s -l ttt/oracle@orcl @ ab.txt 6 1 | ts.awk
[2023-10-19 10:07:03]
[2023-10-19 10:07:03]         ID SUBSTR ROWID              SLEEPT(1)
[2023-10-19 10:07:03] ---------- ------ ------------------ ------------------------------
[2023-10-19 10:07:03]          1 001    AABnNmAAMAAC/JYAAA 2023-10-19 10:06:56.000000000
[2023-10-19 10:07:03]          2 002    AABnNmAAMAAC/IqAAA 2023-10-19 10:06:57.000000000
[2023-10-19 10:07:03]          3 003    AABnNmAAMAAC+78AAA 2023-10-19 10:06:58.000000000
[2023-10-19 10:07:03]          7 007    AABnNmAAMAAC/K8AAA 2023-10-19 10:06:59.000000000
[2023-10-19 10:07:03]          4 004    AABnNmAAMAAC/KSAAA 2023-10-19 10:07:00.000000000
[2023-10-19 10:07:03]          6 006    AABnNmAAMAAC/L2AAA 2023-10-19 10:07:01.000000000
[2023-10-19 10:07:05]          8 008    AABnNmAAMAAC/IgAAA 2023-10-19 10:07:02.000000000
[2023-10-19 10:07:05]         10 010    AABnNmAAMAAC/J7AAA 2023-10-19 10:07:03.000000000
[2023-10-19 10:07:05]          9 009    AABnNmAAMAAC/G5AAA 2023-10-19 10:07:04.000000000
[2023-10-19 10:07:05]
[2023-10-19 10:07:05] 9 rows selected.
[2023-10-19 10:07:05]
[2023-10-19 10:07:05] Elapsed: 00:00:09.01

$ egrep "db file|FETCH" orclcdb_ora_32259.trc
WAIT #140509161269912: nam='db file sequential read' ela= 511 file#=41 block#=782811 blocks=1 obj#=422759 tim=11905890260390   --//索引root
WAIT #140509161269912: nam='db file sequential read' ela= 251 file#=41 block#=782812 blocks=1 obj#=422759 tim=11905890260831   --//索引葉子
WAIT #140509161269912: nam='db file sequential read' ela= 516 file#=41 block#=782936 blocks=1 obj#=422758 tim=11905890261495   --//id=1
FETCH #140509161269912:c=1620,e=1001787,p=3,cr=3,cu=0,mis=0,r=1,dep=0,og=1,plh=3446268138,tim=11905891261547                   
WAIT #140509161269912: nam='db file sequential read' ela= 581 file#=41 block#=782890 blocks=1 obj#=422758 tim=11905891264701   --//id=2
WAIT #140509161269912: nam='db file sequential read' ela= 558 file#=41 block#=782076 blocks=1 obj#=422758 tim=11905892265105   --//id=3
WAIT #140509161269912: nam='db file parallel read' ela= 222 files=1 blocks=4 requests=4 obj#=422758 tim=11905893266587         --//id= 4..7
--//可以看出總是把db file parallel read操作後的最後的記錄id =7優先輸出。
WAIT #140509161269912: nam='db file sequential read' ela= 669 file#=41 block#=782880 blocks=1 obj#=422758 tim=11905896267269   --//id=8
--//因為我加入過濾條件substr(vc,3498,3)<>'005',這樣沒有達到fetch=6的情況,單獨做了一次db file sequential read。
FETCH #140509161269912:c=5071,e=6004437,p=7,cr=8,cu=0,mis=0,r=6,dep=0,og=1,plh=3446268138,tim=11905897268386
WAIT #140509161269912: nam='db file parallel read' ela= 307 files=1 blocks=2 requests=2 obj#=422758 tim=11905897270746         --//id=9,10
FETCH #140509161269912:c=1746,e=2000488,p=2,cr=3,cu=0,mis=0,r=2,dep=0,og=1,plh=3446268138,tim=11905899270318

--//可以看出一個規律,在做db file parallel read操作後,最後的滿足輸出條件的記錄總是優先輸出。
--//至於為什麼我不知道。
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 模板智能數組指針 1.管理任意類型的數組指針 2.釋放的時候自動刪除數組指針指向的記憶體 //模板智能數組指針 template<typename T> class AiArrayPtr { public: AiArrayPtr(T *pArray) { m_pAiPtr = pArray; m_bI ...
  • 通過前面13天的學習,對Dart基礎有了系統的熟悉,今天我們開始學習Dart類和對象,本文主要學習Dart類,包括類方法,構造器,對象類型,實例變數,隱性介面,類變數和類方法等…… ...
  • 【學習課程】:【【小白入門 通俗易懂】2021韓順平 一周學會Linux】 https://www.bilibili.com/video/BV1Sv411r7vd/?p=14&share_source=copy_web&vd_source=2c07d62293f5003c919b2df9b2e054 ...
  • 在 Linux 系統中,/proc和/sys都是特殊的文件系統,數據內容是存放在記憶體中,這兩個目錄文件中的內容由內核動態生成,查看這個文件中的內容,實際上就是查詢內核的某些狀態或信息。 可以將這兩個目錄文件理解為虛擬的目錄,即在硬碟上不存在。 /proc 文件系統 proc 是process(進程) ...
  • 導讀: 本文系原創,歡迎規範轉載。 本文描述瞭如何處理linux虛擬機從xen虛擬化遷移kvm虛擬化遇到問題,包括重建initramfs,處理未卸載的tools等。 系列文章: xen2kvm遷移-Windows篇 xen2kvm遷移-Linux篇 遷移環境: 源平臺:華為FusionCompute ...
  • 痞子衡嵌入式半月刊: 第 83 期 這裡分享嵌入式領域有用有趣的項目/工具以及一些熱點新聞,農曆年分二十四節氣,希望在每個交節之日準時發佈一期。 本期刊是開源項目(GitHub: JayHeng/pzh-mcu-bi-weekly),歡迎提交 issue,投稿或推薦你知道的嵌入式那些事兒。 上期回顧 ...
  • 1. on-my-zsh安裝 1.1. 使用curl方式安裝 1.1.1 官方鏡像源 sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" 1.1.2 國內Git ...
  • 1. 增長 1.1. 在高速的業務環境中,流量可能逐年增長幾個數量級,環境會變得更加複雜,隨之而來的數據需求也會快速增加 1.2. 擴展Web伺服器 1.2.1. 在負載均衡的後端添加更多的伺服器節點,而這通常就是擴展We b伺服器的全部工作 2. 可擴展性 2.1. 系統支撐不斷增長的流量的能力 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...