[20201204]為什麼返回2行記錄.txt

lfree發表於2020-12-07

[20201204]為什麼返回2行記錄.txt

--//在itpub問的問題,http://www.itpub.net/thread-2140116-1-1.html。花了一點點時間,大概知道問題在哪裡,
--//問題出在一致性讀取上,參考連結http://blog.itpub.net/267265/viewspace-2213824/ =>[20180907]訪問v$檢視與一致性讀取.txt

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

SCOTT@book> select sid from v$mystat where rownum=1;
       SID
----------
        32

SCOTT@book> select  sid ,osuser  from v$session where sid = 32;
       SID OSUSER
---------- ------------------------------
        32 oracle
--//返回1行.如果加入提示。

SCOTT@book> alter session set statistics_level = all;
Session altered.

SCOTT@book> select /*+ leading(s e w) */ sid ,osuser  from v$session where sid = 32;
       SID OSUSER
---------- ------------------------------
        32 oracle
        32 oracle

--//檢視執行計劃:
SCOTT@book> @ dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  41djy6556s87h, child number 1
-------------------------------------
select /*+ leading(s e w) */ sid ,osuser  from v$session where sid = 32
Plan hash value: 1247622051
---------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                 | Name            | Starts | E-Rows |E-Bytes| Cost (%CPU)| A-Rows |   A-Time   |  OMem |  1Mem | Used-Mem |
---------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT          |                 |      1 |        |       |     1 (100)|      2 |00:00:00.01 |       |       |          |
|   1 |  NESTED LOOPS             |                 |      1 |      1 |   108 |     0   (0)|      2 |00:00:00.01 |       |       |          |
|   2 |   MERGE JOIN CARTESIAN    |                 |      1 |      1 |    82 |     0   (0)|   1367 |00:00:00.01 |       |       |          |
|*  3 |    FIXED TABLE FIXED INDEX| X$KSUSE (ind:1) |      1 |      1 |    69 |     0   (0)|      1 |00:00:00.01 |       |       |          |
|   4 |    BUFFER SORT            |                 |      1 |    100 |  1300 |     0   (0)|   1367 |00:00:00.01 | 50176 | 50176 |45056  (0)|
|   5 |     FIXED TABLE FULL      | X$KSLED         |      1 |    100 |  1300 |     0   (0)|   1367 |00:00:00.01 |       |       |          |
|*  6 |   FIXED TABLE FIXED INDEX | X$KSLWT (ind:1) |   1367 |      1 |    26 |     0   (0)|      2 |00:00:00.01 |       |       |          |
---------------------------------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$88122447
   3 - SEL$88122447 / S@SEL$4
   5 - SEL$88122447 / E@SEL$4
   6 - SEL$88122447 / W@SEL$4
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - filter(("S"."INDX"=32 AND "S"."INST_ID"=USERENV('INSTANCE') AND BITAND("S"."KSSPAFLG",1)<>0 AND BITAND("S"."KSUSEFLG",1)<>0))
   6 - filter(("W"."KSLWTSID"=32 AND "W"."KSLWTEVT"="E"."INDX"))

--//你可以發現id=6,A-Row確實返回2行,為什麼呢?

2.繼續探究:
--//開啟新的會話,原來會話不退出。
SCOTT@book> select /*+ leading(s e w) */ sid ,osuser  from v$session where sid = 32;

       SID OSUSER
---------- ------------------------------
        32 oracle

--//相同的提示僅僅返回一行。再問為什麼呢?
--//先猜測一下X$KSLWT,從名字上可以猜測是等待事件相關的檢視。顯示多加入幾個欄位:
SCOTT@book> select /*+ leading(s e w) */ sid ,osuser,EVENT#,event  from v$session where sid = 32;
       SID OSUSER                             EVENT# EVENT
---------- ------------------------------ ---------- ----------------------------------------
        32 oracle                                354 SQL*Net message from client

--//回到原來的會話,重複執行:
SCOTT@book> select /*+ leading(s e w) */ sid ,osuser,EVENT#,event  from v$session where sid = 32;
       SID OSUSER                             EVENT# EVENT
---------- ------------------------------ ---------- ----------------------------------------
        32 oracle                                350 SQL*Net message to client
        32 oracle                                354 SQL*Net message from client

--//這樣就很好解析為什麼返回2行了。檢視不能保證一致性。
--//該語句執行時先出現SQL*Net message to client等待,然後是SQL*Net message from client等待。
--//由於檢視一致性無法保證,就出現返回2行的情況。而另外的會話在不會出現這樣的情況。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-2740080/,如需轉載,請註明出處,否則將追究法律責任。

相關文章