SQL
>
show parameter open_cursors
--
每個session(會話)最多能同時打開多少個cursor(游標)
NAME TYPE VALUE
--
---------------------------------- ----------- ------------------------------
open_cursors
integer
300
SQL
>
show parameter session_cached_cursor
--
每個session(會話)最多可以緩存多少個關閉掉的cursor
NAME TYPE VALUE
--
---------------------------------- ----------- ------------------------------
session_cached_cursors
integer
20
SQL
>
select
count
(
*
)
from
v$open_cursor;
--
是指當前實例的某個時刻的打開的cursor數目
COUNT
(
*
)
--
--------
108
1、open_cursors與session_cached_cursor的作用?
open_cursors設定每個session(會話)最多能同時打開多少個cursor(游標)。session_cached_cursor
設定每個session(會話)最多可以緩存多少個關閉掉的cursor。想要弄清楚他們的作用,我們得先弄清楚oracle如何執行每個sql語句。
看完上圖后我們明白了兩件事:
a、兩個參數之間沒有任何關系,相互也不會有任何影響。
b、兩個參數有著相同的作用:讓后續相同的sql語句不在打開游標,從而避免軟解析過程來提供應用程序的效率。
2、如何正確合理設置參數的大小?
a、如果Open_cursors設置太小,對系統性能不會有明顯改善,還可能觸發ORA-O1000:m~imum
open CUrsOrs exceeded.的錯誤。如果設置太大,則無端消耗系統內存。我們可以通過如下的sql語句查看你的設置是否合理:
SQL
>
SELECT
MAX
(A.VALUE)
AS
HIGHEST_OPEN_CUR, P.VALUE
AS
MAX_OPEN_CUR
2
FROM
V$SESSTAT A, V$STATNAME B, V$PARAMETER P
3
WHERE
A.STATISTIC#
=
B.STATISTIC#
4
AND
B.NAME
=
'
opened cursors current
'
5
AND
P.NAME
=
'
open_cursors
'
6
GROUP
BY
P.VALUE;
HIGHEST_OPEN_CUR MAX_OPEN_CUR
--
-------------- --------------------
28
300
HIGHEST_ OPEN CUR是實際打開的cursors 的最大值,MAX_OPEN_
CUR是參數Open_cursors的設定值,如果二者太接近,甚至觸發eRA一01000錯誤,那么你就應該調大參數Open_cursors的設定
值。如果問題依舊沒有解決,盲目增大Open_cursors也是不對的,這個時候你得檢查應用程序的代碼是否合理,比如說應用程序是否打開了游標,卻沒
有在它完成工作后沒有及時關閉。以下語句可以幫助你確定導致游標漏出的會話:
SELECT
A.VALUE, S.USERNAME, S.SID, S.SERIAL#
FROM
V$SESSTAT A, V$STATNAME B, V$SESSION S
WHERE
A.STATISTIC#
=
B.STATISTIC#
AND
S.SID
=
A.SID
AND
B.NAME
=
'
opened cursors curent
'
;
同樣,session_cached_cursors的值也不是越大越好,我們可以通過下面兩條語句得出合理的設置。
SQL
>
SELECT
NAME, VALUE
FROM
V$SYSSTAT
WHERE
NAME
LIKE
'
%cursor%
'
;
NAME VALUE
--
-------------------------------------------------------------- ----------
opened cursors cumulative
15095
opened cursors
current
34
session
cursor
cache hits
12308
session
cursor
cache
count
775
cursor
authentications
324
SQL
>
SELECT
NAME, VALUE
FROM
V$SYSSTAT
WHERE
NAME
LIKE
'
%parse%
'
;
NAME VALUE
--
-------------------------------------------------------------- ----------
parse time cpu
332
parse time elapsed
1190
parse
count
(total)
9184
parse
count
(hard)
1031
parse
count
(failures)
3
session cursor cache hits就是系統在高速緩存區中找到相應cursors的次數,parse
count(total)就是總的解析次數,二者比值越高,性能越好。如果比例比較低,并且有較多剩余內存的話,可以考慮加大該參數。
c、使用下面的sql判斷'session_cached_cursors' 的使用情況。如果使用率為100%則增大這個參數值。
SQL
>
SELECT
'
session_cached_cursors
'
PARAMETER,
2
LPAD(VALUE,
5
) VALUE,
3
DECODE(VALUE,
0
,
'
n/a
'
, TO_CHAR(
100
*
USED
/
VALUE,
'
990
'
)
||
'
%
'
) USAGE
4
FROM
(
SELECT
MAX
(S.VALUE) USED
5
FROM
V$STATNAME N, V$SESSTAT S
6
WHERE
N.NAME
=
'
session cursor cache count
'
7
AND
S.STATISTIC#
=
N.STATISTIC#),
8
(
SELECT
VALUE
FROM
V$PARAMETER
WHERE
NAME
=
'
session_cached_cursors
'
)
9
UNION
ALL
10
SELECT
'
open_cursors
'
,
11
LPAD(VALUE,
5
),
12
TO_CHAR(
100
*
USED
/
VALUE,
'
990
'
)
||
'
%
'
13
FROM
(
SELECT
MAX
(
SUM
(S.VALUE)) USED
14
FROM
V$STATNAME N, V$SESSTAT S
15
WHERE
N.NAME
IN
16
(
'
opened cursors current
'
,
'
session cursor cache count
'
)
17
AND
S.STATISTIC#
=
N.STATISTIC#
18
GROUP
BY
S.SID),
19
(
SELECT
VALUE
FROM
V$PARAMETER
WHERE
NAME
=
'
open_cursors
'
);
PARAMETER VALUE USAGE
--
-------------------- ---------- -----
session_cached_cursors
20
100
%
open_cursors
300
16
%
當我們執行一條sql語句的時候,我們將會在shared pool產生一個library cache object,cursor就是其中針對于sql語句的一種library cache object.另外我們會在pga有一個cursor的拷貝,同時在客戶端會有一個statement handle,這些都被稱為cursor,在v$open_cursor里面我們可以看到當前打開的cursor和pga內cached cursor.
session_cached_cursor
這個參數限制了在pga內session cursor cache list的長度,session cursor cache list是一條雙向的lru鏈表,當一個session打算關閉一個cursor時,如果這個cursor的parse count超過3次,那么這個cursor將會被加到session cursor cache list的MRU端.當一個session打算parse一個sql時,它會先去pga內搜索session cursor cache list,如果找到那么會把這個cursor脫離list,然后當關閉的時候再把這個cursor加到MRU 端.session_cached_cursor提供了快速軟分析的功能,提供了比soft parse更高的性能.
更新2:
OPEN_CURSORS是一個十分有趣的參數,經常有DBA發現自己的系統中的OPEN CURSORS十分大。我們看一個例子:
SQL
>
select
sid,value
from
v$sesstat a,v$statname b
where
a.statistic#
=
b.statistic#
and
name
=
'
opened cursors current
'
order
by
2
;
SID VALUE
--
-------- ----------
5430
93
3527
95
4055
96
4090
97
2012
98
1819
98
5349
102
1684
103
1741
116
4308
169
1970
170
1369
181
4208
184
887
214
5215
214
3518
214
868
214
1770
215
4050
215
1809
231
3010
235
762
237
731
471
4013
1066
2648
1152
2255
1172
2322
2620
我們看到這個系統的
OPEN_CURSORS
參數設置為
3000
,而會話中當期打開
CURSOR
最大的會話居然達到了
2620
。在一般人的眼里,
CURSOR
使用后就關閉了,
OPENEDCURSORS
的數量應該不會太多,難道應用程序出現了
CURSOR
泄漏,有些應用使用了
CURSOR
沒有關閉?實際上我們對
OPENCURSOR
的概念一直存在誤解。認為只有正在
FETCH
的
CURSOR
是
OPEN
狀態的,而一旦
FETCH
結束,
CLOSECURSOR
后,
CURSOR
就處于關閉狀態了。因此一個會話中
OPEN
狀態的
CURSOR
數量應該很少。事實上不是這樣的,某些
CURSOR
在程序中是已經
CLOSE
了,但是
Oracle
為了提高
CURSOR
的性能,會對其進行緩沖,這些緩沖的
CURSOR
,在程序中的關閉只是一個軟關閉,事實上,在會話中并未關閉,而是放在一個
CURSOR
緩沖區中。
在
Oracle9.2.0.5
之前,
OPEN_CURSORS
參數的作用是雙重的,一方面是限制一個會話打開的
CURSORS
的總量。另外一方面,
OPEN_CURSORS
參數也作為
PL/SQLCURSOR
的緩沖。在
PL/SQL
中,如果某個
CURSOR
關閉了,這個
CURSOR
不會馬上硬關閉,而是首先保存在
CURSOR
緩沖中。如果這個會話當前打開的
CURSOR
數量還沒有達到
OPEN_CURSORS
參數的值,那么就可以先保持
OPEN
狀態。如果當前打開的
CURSOR
數量已經達到了
OPEN_CURSORS
參數的限制,那么首先會關閉一個被緩沖的,實際當時并未打開的
CURSOR
。如果緩沖池中的所有
CURSOR
都是實際打開的,那么就會報
ORA-1000
,
"maximumopencursorsexceeded"
。
Oracle9.2.0.5
以后,
OPEN_CURSORS
參數不再承擔
PL/SQL
緩沖的工作
,PL/SQL
中的
SQL
也可以使用
SESSION_CACHED_CURSORS
的會話緩沖了。這個參數就成為了一個純粹的限制。
雖然如此,
OPEN_CURSORS
參數仍然和
CURSOR
的緩沖機制密切相關,因為這個參數限制了當前某個會話打開
CURSOR
的最大值。設置一個較大的
OPEN_CURSORS
參數,可以避免出現
ORA-1000
,同時也可以讓會話緩沖更多的
CURSOR
,改善
SQL
解析的性能。不過這個參數設置的較大會占用較大的
PGA
空間,消耗一定的物理內存。因此這個參數也不是設置的越大越好,一般的
OLTP
系統中,
1000
-
3000
就足夠了。在共享服務器模式的系統中,這個參數的設置要略微保守一些,因為這個參數越大,占用的
SGA
空間也就越大。
另外要注意的是,從
Oracle9.0
開始,這個參數就已經是動態的了,可以隨時動態調整。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

