1. 程式人生 > >轉 如何診斷和解決high version count 10.2.0.4

轉 如何診斷和解決high version count 10.2.0.4

determine sel add 兩種 引入 data sql 語句 當前 base

轉自

http://blog.csdn.net/notbaron/article/details/50927492

在Oracle 10g以上的版本,High version count可謂是一個臭名昭著的問題。Hight version count不僅僅產生的原因多種多樣,並且會導致各種令人頭痛的問題,輕導致數據庫的性能急劇下降,CPU利用率劇增,重則導致數據庫掛起,觸發ORA-04031或者其它bug導致宕機。

什麽是verion count,什麽是high?

在弄清楚診斷和解決這個問題之前,首先需要清楚什麽是version count,什麽是high?換而言之就是產生version count的原因,多高的version count才算high。

一個SQL 第一次執行時,會進行硬解析,同時創建parent cursor 和child cursor。

當再次執行這個SQL時,那麽首先會對SQL 語句進行特殊的hash 運算,對應生成一個hash value。Hash value存放在parent cursor中,然後會用這個hash value到paranet cursor的bucket中匹配,如果相同的hash value 已存在parent cursor裏,則繼續遍歷這個child cursor,如果可重用,那麽就沿用child cursor的信息,如果不能重用,就會重新生成一個新的child cursor。

一個parent cursor下child cursor 的總數,就是這個SQL的version count。

事實上,我們很難去準確定義一個high version count的值,只能根據不同的系統來判斷是否為high verison count。在AWR報告中,默認verion count超過20的SQL就會顯示在order by version count一欄中。根據經驗version count如果超過100,可能就需要引起註意了。

我們可以通過查看v$sqlarea視圖的loaded_versions來判斷當前這個SQL的version count是多少,然後再通過address的值來查詢v$sql_shared_cursor視圖看那些字段的返回值為Y,Y代表mismatch。Mismatch是引起產生version count的直接原因。通常我們可以綜合:

v$sqlarea, v$sql_shared_cursor, v$sql_bind_metadata, v$sql_bind_captures來診斷這類問題,但是手工去查這些表往往過於繁瑣, Abel Macias 開發了一個小工具叫做version_rpt,這個工具可以用來診斷導致是那個模塊出現mismatch,從而導致了high version count。我們可以到High SQL Version Counts – Script to determine reason(s) (DOC ID 438755.1)上下載這個小工具。

Cursortrace和cursordump

當然有時候我們會遇到某些SQL的$sql_shared_cursor所有的字段的結果都為N,但是其version count還是很高的情況,那麽這些查詢這些視圖就不管用了,主要的原因是存在部分bug,可能導致v$sql_shared_cursor的信息不準確。例如:

Bug 12539487 – gv$sql_shared_cursor may not show all reasons to not share a cursor (Doc ID 12539487.8)

所以在10g以上版本可以使用cursortrace來查找high version count的原因。

可以使用以下方式打開cursortrace:

SQL>alter system set events

‘immediate trace name cursortrace level 577, address <hash_value>‘;

其中可以使用三個level,level 1為577, level 2為578, level 3為580(實際上還有其它level,只是沒有文檔記載)

如需關閉cursortrace,則可以使用以下方式進行關閉:

SQL>alter system set events

‘immediate trace name cursortrace level 2147483648, address 1‘;

或者使用以下方式關閉:

SQL>alter session set events ‘immediate trace name cursortrace level 128 , address <address>‘;

當然也可以通過oradebug的方式來進行cursortrace,這裏就不詳述了。

註意在10.2.0.4以下版本存在Bug 5555371導致cursortrace無法徹底關閉的情況,最終導致其trace文件不停的增長,從而可能導致oracle文件系統被撐爆的現象。

在實際幫助客戶處理查找high version count的原因時,我們發現即使在10.2.0.5以上的版本也可能會出現cursortrace無法徹底關閉的現象。

如果數據庫版本在10.2.0.4 以下,生產系統上不建議使用cursortrace ,

生產環境在10.2.0.4 以上版本,建議謹慎使用cursortrace 。例如註意觀察,如果無法關閉則通過修改MAX_DUMP_FILE_SIZE 參數限制cursortrace trace 文件的最大大小,或者寫一個crontab 的job 定期清理其trace 文件。

在11g中引入cursordump,我們可以使用如下方式進行cursor dump:

alter system set events ‘immediate trace name cursordump level 16‘

這種方式收集的信息比較全:例如它可以采集到部分別的方式無法看到的px_mismatch以及它會進一步展開optimizer_mismatch的信息等。

在10gR2版本中, 我們更傾向於使用processstate dump和errorstack的信息來替代cursordump,因為processstate dump中也存在cursordump的信息:

先找到high version count SQL對應的spid,然後執行以下SQL:

SQL>oradebug setospid

SQL>oradebug ulimit

SQL>oradebug dump processstate 10

SQL>oradebug dump errorstack 3

一些可能導致問題的SQL和配置

我們通常可以使用AWR和ASH來找出這些可能存在問題的SQL。根據以往的經驗,最容易導致出現version count的SQL包括以下類型:(只是列出最常見的寫法,並不是很全)

1. Insert 語句使用綁定變量

Insert into table(column1, column2, column128, …) values (:1, :2, :3, … :128, …)

尤其是對於某些表字段類型特別多的,並且把這個表所有字段都寫到insert語句裏面的表現得尤為明顯。

2. select into 語句使用綁定變量

select a, b, c, … into :1,:2,:3 from table1

3. 使用insert … returning 語句

4. 使用一個很長的inlist ,並且裏面都是綁定變量

select * from table where column1 in (1, :2, :3, … :128, …)

5. SQL 非常長並且裏面帶有多個綁定變量

如果一個SQL語句特別長,並且使用了綁定變量,那麽這樣的SQL更傾向於出現high version count。

6. Dblink 調用SQL 語句,最好不要使用綁定變量

Bug 12320556 High version count for child cursors referencing a remote object due to AUTH_CHECK_MISMATCH

這一類語句其實從應用的層面都比較好改寫,改寫的思路如下:

  1. 對於insert into 或者select into可以考慮不要使用綁定變量。
  2. 對於一個字段很多的表,在insert的時候不要把所有字段都列出來
  3. 盡量不要使用insert into這樣生僻的寫法
  4. 對於inlist 應該控制其內部綁定變量的個數,如果無法控制,則可以將這些變量存入到一張臨時表中,去掉inlist,要用的時候再從臨時表獲取。
  5. 盡量不要寫特別長的SQL語句,這種SQL不僅易讀性差難於維護,並且很容易導致shared pool的一些爭用。
  6. 盡量避免在dblink調用的SQL語句中使用綁定變量。

在配置方面, cursor_sharing和Adaptive cursor sharing的設置不當容易導致high version count的問題。

請不要使用cursor_sharing=similar ,這句話再怎麽強調都不過分。

ANNOUNCEMENT: Deprecating the cursor_sharing = ‘SIMILAR’ setting (Doc ID 1169017.1)

在10gR2以上版本,cursor_sharing設置為similar可能會導致各種各樣的bug,其中之一就是可能會導致出現大量的不可共享的child cursor,從而引發出high version count的問題。

Oracle在12c已經不支持cursor_sharing=similar, 在11.2.0.3版本,cursor_sharing設置為similar與設置為force的效果相同。

另外cursor_sharing最好設置為exact,在沒有經過充分的測試下,不要將其設置為force。因為設置為force同樣有一定的幾率可能導致high version count。

參見: High Version Count with CURSOR_SHARING = SIMILAR or FORCE (Doc ID 261020.1)

如果SQL 語句的共享性很差,首先要做的應該是對SQL 進行調整,而不是調整cursor_sharing 參數。

在11g中引入的adaptive cursor sharing(ACS)特性。在沒有經過充分測試之前,請關閉此特性,這個特性很容易導致high version count的問題。

Bug 12334286 High version counts with CURSOR_SHARING=FORCE (BIND_MISMATCH and INCOMP_LTRL_MISMATCH)

Bug 7213010 – Adaptive cursor sharing generates lots of child cursors

Bug 8491399 – Adaptive Cursor Sharing does not match the correct cursor version for queries using CHAR datatype

常見的bug和workaround

在10gR2版本中存在一個臭名昭著並且隱匿得很深的Bug,它們曾經折磨過無數DBA:

Patch 6795880: BATCH JOBS HANG WAITING ON ‘KKSFBC CHILD COMPLETION’

Bug 8575528 Missing entries in V$MUTEX_SLEEP.location

這兩個bug本質是同一個問題,只是因為前一個問題修復不徹底,反而導致了後一個問題。它存在的缺陷在於如果high version count的SQL,那麽去查找child cursor的過程中效率會非常低,從而導致kksSearchChildList/ kqlfMutexClnFetch這些過程會導致掛起。數據庫的等待事件上表現為大量的latch,mutex等待,典型的有latch: library cache lock, kksfbc child completion, cursor: mutex pin S, Latch: Row Cache Objects, library cache: mutex X。而這些等待事件基本都是平時難得一見的奇觀。

最終的結果往往有兩種:

  1. 數據庫一直掛起必須手工重啟;
  2. 數據庫掛起一段時間,然後恢復
  3. 系統資源耗竭導致宕機
  4. 觸發出其它的bug例如某ORA-600 [kkssearchchildlist*]或者ORA-07445[kkssearchchildlist*]導致數據庫宕機

這個問題號稱在10.2.0.5已經修復,但是這個問題在10.2.0.5版本上依然很常見。主要原因有兩點:

  1. 10.2.0.5雖然包含了修復這個問題的代碼,但是默認情況下是不生效的,需要用戶手工將”_cursor_features_enabled” = 10。
  2. 即使設置了”_cursor_features_enabled” = 10,依然還有遇到KKSFBC CHILD COMPLETION的概率,根本原因還是在於child cursor過多,這一系列的函數調用過程依然過於低效。

遺憾的是如果在10.2.0.5以上版本碰到這個問題,除了按照上文的要求調整SQL或者升級到11gR2以外,從數據庫現有的手段幾乎無解。

另外一個常見的問題是數據表義使用varchar類的變長字符串類型,而應用可能傳入的字符串長度為個位數,也可能傳入的字符串長度為四位數。換而言之,就是應用程序傳入變量的長度範圍過大,導致bind mismatch,最終child cursor不能共享從而重新進行hard parse,這樣的結果就導致child cursor的急劇膨脹。

根據

This is due to the bind buffer mismatch of the current child cursor. If oracle is unable to bind the current value to the existing child cursors bind buffer, oracle upgrades the existing child cursor with a high bind buffer. This will force the query to do a hard parse and a new child cursor will be created. The previous one will be marked ‘dont use’.

這個問題可以通過設置固定的字符串buffer的長度來減少其對應的version count。通過level為4000的10503事件來達到此目的,註意這裏的4000為字符串buffer的長度。在SQL中可變字符串varchar2最大的長度為4000。

SQL>alter system set events ‘10503 trace name context forever, level 4000‘;

還有一個非常有殺傷力的Bug為

Bug 8981059 High Version Count (due to USER_BIND_PEEK_MISMATCH) with bind peeking

這個Bug幾乎影響了所有的10gR2的版本。

這個bug典型的cursor dump信息如下:

KKSCS sharing succeed xsc=1106ac818 childno=3370 reason=BND

Checking for already pinned child. fbcflg 1

Object is invalid

No valid child pinned

Parent 70000065e35bb50(70000065f702598) ready for search

kksSearchChildList outside while loop

kksCheckCursor: next child is #3370

kksCheckCursor: pinning child #3370 in shared mode 70000065e35b960

0000065f41e8f0

KSCS sharing succeed xsc=1106ac818 childno=3370 reason=NFP

KSCS sharing succeed xsc=1106ac818 childno=3370 reason=SQT

KSCS sharing succeed xsc=1106ac818 childno=3370 reason=OPT

...

KSCS sharing succeed xsc=1106ac818 childno=3370 reason=BDM

...

KSCS sharing failed xsc=1106ac818 childno=3370 reason=UBP

kksUnlockChild: releasing child

Failed sharing : 8000000

kksCheckCursor: next child is #3402

kksCheckCursor: pinning child #3402 in shared mode 70000065e35b960

0000065e615f88

KKSCS sharing succeed xsc=1106ac818 childno=3402 reason=NFP

KKSCS sharing succeed xsc=1106ac818 childno=3402 reason=SQT

在堆棧信息中還會找到kksfbc以及 kksLoadChild這樣的函數。

這個問題實際上是因為綁定變量窺測導致的child cursor不能共享。並且在某些情況下可能導致查詢出來的結果是錯誤的,也就是我們所說的wrong result。

通常這一類問題在10.2.0.5以上版本可以通過關閉綁定變量窺測來規避:

SQL>alter system set "_optim_peek_user_binds"=false
  • 監控version count特別高的語句,如果到了特定的閾值,就將其從shared pool中踢出去,在10.2.0.4和10.2.0.5通過以下方式清除特定的SQL:
SQL>alter session set events ‘5614566 trace name context forever‘;

SQL>exec dbms_shared_pool.purge(‘&address, &hash_value‘, c);

前面event 5614566設置的目的是為了規避Bug 5614566導致的使用dbms_shared_pool.purge 無法將parent cursor清除出shared pool的問題。

雖然Bug 5614566在10.2.0.5已經修復,但是在某些情況下,依然會遇到dbms_shared_pool.purge的情況。

  • 使用dbms_shared_pool.keep這個包將特定high version count的SQL進行keep。

此建議為Bug 10157392 High version counts for SQL with binds (BIND_MISMATCH)給出的一個workaround,這種方法大多數情況都不起作用。

  • 定期的對shared pool進行flush。

在某些負載比較低的系統中,可以考慮使用這種方法來防治high version count的問題。在業務繁忙的系統中刷新shared pool存在很大的風險,以來大量被刷出去的SQL需要重新進行硬解析,有可能會導致CPU短時間內的迅速增加。還有就是某些SQL被刷出shared pool以後重新解析其執行計劃可能會發生變化,由此容易造成性能的不穩定。

11g的cursor特性的增強

在10gR2中,child cursor的最大上限為32768。Child cursor的數量如果超過了32768,那麽這個session就會拋出ORA-600 [17059]的錯誤,然後這個session就會crash,在10.2.0.4和10.2.0.5上有一個增強補丁:Bug 8946311 Increase max children before reporting ORA-600 [17059]。如果應用了這個patch,那麽child cursor的上限就可以提高到65535了。

但是允許child cursor的上限到一個非常大的值並不是什麽好主意,只能暫時緩解因為high version count而導致的ORA-00600的錯誤。但是同時也會引發新的問題,例如最典型的是因為child cursor過多,導致了單個SQL語句占用的shared pool的空間非常大,最終導致ORA-004031.

到了11g,Oracle已經充分意識到high version count是一個很嚴重的問題,盡管mismatch是客觀存在的,但是可以通過其它的一些手段限制child cursor的數量。

Enhancement Request Bug 10187168 : OBSOLETE PARENT CURSORS IF VERSION COUNT EXCEEDS A THRESHOLD 引入了一個隱含參數叫_cursor_obsolete_threshold,此參數用來限制單個parent cursor下child cursor的數量,默認值為100。如果child cursor的數量超過了這個閾值就會cursor obsolescence的特性,也就是說這個時候parent cursor會被廢棄,並且同時重新創建一個新的parent cursor。 這樣雖然mismatch會繼續存在,但是一勞永逸的解決的high version count的問題。這個patch已經集成到11.2.0.3版本。如果低於11.2.0.3版本,除了需要應用這個patch,同時需要設置一下參數:

11.2.0.1:

SQL> alter system set "_cursor_features_enabled"=34 scope=spfile;

SQL> alter system set event=‘106001 trace name context forever,level 1024‘ scope=spfile;

11.2.0.2:

SQL> alter system set "_cursor_features_enabled"=1026 scope=spfile;

SQL> alter system set event=‘106001 trace name context forever,level 1024‘ scope=spfile;

小結

High version count由於產生原因紛繁多樣,並且產生的結果表現形式各不相同,再加上其復雜的診斷方法,往往令很多DBA都束手無策,這不能不說是早期產品設計上的一個缺陷。好在從11gR2開始,通過_cursor_obsolete_threshold這個特性,我們很快可以和high version count說再見了。但是探索的過程永遠比結果重要,我們收獲到的不僅僅是知識,而是一種鉆研的精神。

################Bug 7122093 : LIBRARY CACHE CHILD LATCH HELD FOR EXCESSIVE TIME IF SCAN X$KGLDP


dr: 7122093 10.2.0.3 RDBMS 10.2.0.3 LIB CACHE PRODID-5 PORTID-23
Abstract: LIBRARY CACHE CHILD LATCH HELD FOR EXCESSIVE TIME IF SCAN X$KGLDP

*** 05/23/08 01:57 pm ***
Logged out of bug 7116507 for clarity
The customer issue involves a third party monitoring tool.
The test here is simplified just to show the underlying problem.
=========================
PROBLEM:
Under certain conditions a scan of the X$KGLDP fixed table
can cause very long latch hold times of a child library cache latch
causing an instance wide hang.
In particular if a cursor has a high version_count in V$SQLAREA
ie; has a lot of child cursors, and if it depends on a lot of
other objects.


####################
Bug 7122093 - ‘latch: library cache‘ contention caused by queries on V$ views. (文檔 ID 7122093.8)


Description

Querying [G]V$ views based on X$KGLDP can hold library cache child latches for
too long potentially causing ‘latch: library cache‘ contention.


###############################
Troubleshooting: High Version Count Issues (文檔 ID 296377.1)

**BIND_MISMATCH

The bind metadata does not match the existing child cursor. For example, in the following, the definition of the bind variable ‘a‘ has changed
between the 2 statements:

variable a varchar2(100);
select count(*) from emp where ename = :a ->> 1 PARENT, 1 CHILD

variable a varchar2(400);
select count(*) from emp where ename = :a ->> 1 PARENT, 2 CHILDREN

###ORACLE 10G

http://blog.csdn.net/notbaron/article/details/50927492

在10gR2以上版本,cursor_sharing設置為similar可能會導致各種各樣的bug,其中之一就是可能會導致出現大量的不可共享的child cursor,從而引發出high version
count的問題。

Oracle在12c已經不支持cursor_sharing=similar, 在11.2.0.3版本,cursor_sharing設置為similar與設置為force的效果相同。

另外cursor_sharing最好設置為exact,在沒有經過充分的測試下,不要將其設置為force。因為設置為force同樣有一定的幾率可能導致high version count。

參見: High Version Count with CURSOR_SHARING = SIMILAR or FORCE (Doc ID 261020.1)

如果SQL 語句的共享性很差,首先要做的應該是對SQL 進行調整,而不是調整cursor_sharing 參數。

在11g中引入的adaptive cursor sharing(ACS)特性。在沒有經過充分測試之前,請關閉此特性,這個特性很容易導致high version count的問題。

Bug 12334286 High version counts with CURSOR_SHARING=FORCE (BIND_MISMATCH and INCOMP_LTRL_MISMATCH)

Bug 7213010 – Adaptive cursor sharing generates lots of child cursors

Bug 8491399 – Adaptive Cursor Sharing does not match the correct cursor version for queries using CHAR datatype

常見的bug和workaround

在10gR2版本中存在一個臭名昭著並且隱匿得很深的Bug,它們曾經折磨過無數DBA:

Patch 6795880: BATCH JOBS HANG WAITING ON ‘KKSFBC CHILD COMPLETION’

Bug 8575528 Missing entries in V$MUTEX_SLEEP.location

這兩個bug本質是同一個問題,只是因為前一個問題修復不徹底,反而導致了後一個問題。它存在的缺陷在於如果high version count的SQL,那麽去查找child cursor的
過程中效率會非常低,從而導致kksSearchChildList/ kqlfMutexClnFetch這些過程會導致掛起。數據庫的等待事件上表現為大量的latch,mutex等待,典型的有latch:
library cache lock, kksfbc child completion, cursor: mutex pin S, Latch: Row Cache Objects, library cache: mutex X。而這些等待事件基本都是平時難得一
見的奇觀。

最終的結果往往有兩種:

數據庫一直掛起必須手工重啟;
數據庫掛起一段時間,然後恢復
系統資源耗竭導致宕機
觸發出其它的bug例如某ORA-600 [kkssearchchildlist*]或者ORA-07445[kkssearchchildlist*]導致數據庫宕機
這個問題號稱在10.2.0.5已經修復,但是這個問題在10.2.0.5版本上依然很常見。主要原因有兩點:

10.2.0.5雖然包含了修復這個問題的代碼,但是默認情況下是不生效的,需要用戶手工將”_cursor_features_enabled” = 10。
即使設置了”_cursor_features_enabled” = 10,依然還有遇到KKSFBC CHILD COMPLETION的概率,根本原因還是在於child cursor過多,這一系列的函數調用過程依然
過於低效。
遺憾的是如果在10.2.0.5以上版本碰到這個問題,除了按照上文的要求調整SQL或者升級到11gR2以外,從數據庫現有的手段幾乎無解。

另外一個常見的問題是數據表義使用varchar類的變長字符串類型,而應用可能傳入的字符串長度為個位數,也可能傳入的字符串長度為四位數。換而言之,就是應用程序
傳入變量的長度範圍過大,導致bind mismatch,最終child cursor不能共享從而重新進行hard parse,這樣的結果就導致child cursor的急劇膨脹。

根據

This is due to the bind buffer mismatch of the current child cursor. If oracle is unable to bind the current value to the existing child cursors bind
buffer, oracle upgrades the existing child cursor with a high bind buffer. This will force the query to do a hard parse and a new child cursor will
be created. The previous one will be marked ‘dont use’.

這個問題可以通過設置固定的字符串buffer的長度來減少其對應的version count。通過level為4000的10503事件來達到此目的,註意這裏的4000為字符串buffer的長度。
在SQL中可變字符串varchar2最大的長度為4000。

SQL>alter system set events ‘10503 trace name context forever, level 4000‘;
還有一個非常有殺傷力的Bug為

Bug 8981059 High Version Count (due to USER_BIND_PEEK_MISMATCH) with bind peeking

這個Bug幾乎影響了所有的10gR2的版本。

這個bug典型的cursor dump信息如下:

KKSCS sharing succeed xsc=1106ac818 childno=3370 reason=BND

Checking for already pinned child. fbcflg 1

Object is invalid

No valid child pinned

Parent 70000065e35bb50(70000065f702598) ready for search

kksSearchChildList outside while loop

kksCheckCursor: next child is #3370

kksCheckCursor: pinning child #3370 in shared mode 70000065e35b960

0000065f41e8f0

KSCS sharing succeed xsc=1106ac818 childno=3370 reason=NFP

KSCS sharing succeed xsc=1106ac818 childno=3370 reason=SQT

KSCS sharing succeed xsc=1106ac818 childno=3370 reason=OPT

...

KSCS sharing succeed xsc=1106ac818 childno=3370 reason=BDM

...

KSCS sharing failed xsc=1106ac818 childno=3370 reason=UBP

kksUnlockChild: releasing child

Failed sharing : 8000000

kksCheckCursor: next child is #3402

kksCheckCursor: pinning child #3402 in shared mode 70000065e35b960

0000065e615f88

KKSCS sharing succeed xsc=1106ac818 childno=3402 reason=NFP

KKSCS sharing succeed xsc=1106ac818 childno=3402 reason=SQT
在堆棧信息中還會找到kksfbc以及 kksLoadChild這樣的函數。

這個問題實際上是因為綁定變量窺測導致的child cursor不能共享。並且在某些情況下可能導致查詢出來的結果是錯誤的,也就是我們所說的wrong result。

通常這一類問題在10.2.0.5以上版本可以通過關閉綁定變量窺測來規避:

SQL>alter system set "_optim_peek_user_binds"=false
監控version count特別高的語句,如果到了特定的閾值,就將其從shared pool中踢出去,在10.2.0.4和10.2.0.5通過以下方式清除特定的SQL:
SQL>alter session set events ‘5614566 trace name context forever‘;

SQL>exec dbms_shared_pool.purge(‘&address, &hash_value‘, c);
前面event 5614566設置的目的是為了規避Bug 5614566導致的使用dbms_shared_pool.purge 無法將parent cursor清除出shared pool的問題。

雖然Bug 5614566在10.2.0.5已經修復,但是在某些情況下,依然會遇到dbms_shared_pool.purge的情況。

使用dbms_shared_pool.keep這個包將特定high version count的SQL進行keep。
此建議為Bug 10157392 High version counts for SQL with binds (BIND_MISMATCH)給出的一個workaround,這種方法大多數情況都不起作用。

定期的對shared pool進行flush。
在某些負載比較低的系統中,可以考慮使用這種方法來防治high version count的問題。在業務繁忙的系統中刷新shared pool存在很大的風險,以來大量被刷出去的SQL
需要重新進行硬解析,有可能會導致CPU短時間內的迅速增加。還有就是某些SQL被刷出shared pool以後重新解析其執行計劃可能會發生變化,由此容易造成性能的不穩定

轉 如何診斷和解決high version count 10.2.0.4