Oracle學習之性能優(yōu)化(二)游標-創(chuàng)新互聯(lián)

 游標是cursor的中文翻譯,那么到底什么是cursor呢?Oracle Concept中是這樣描述的:

創(chuàng)新互聯(lián)專注于沂源企業(yè)網(wǎng)站建設,成都響應式網(wǎng)站建設公司,成都做商城網(wǎng)站。沂源網(wǎng)站建設公司,為沂源等地區(qū)提供建站服務。全流程專業(yè)公司,專業(yè)設計,全程項目跟蹤,創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務

 When an application issues a SQL statement, the application makes a parse call to the database to prepare the statement for execution. The parse call opens or creates acursor, which is a handle for the session-specific private SQL area that holds a parsed SQL statement and other processing information. The cursor and private SQL area are in the PGA.

如果上述很多的專業(yè)術語把你搞暈了,那你可以簡單的理解成,一個sql語句就會對應到一個游標。

游標分類:

  • session cursor 其實就是指跟這個session相對應的server process的PGA里(準確的說是UGA)的一塊內(nèi)存區(qū)域(或者說內(nèi)存結構),它的目的是為了處理且一次只處理一條sql語句。

  • shared cursor 緩存在librarycache(SGA下的Shared Pool)里的一種library cache object,說白了就是指緩存在library cache里的sql和匿名pl/sql。

如下圖描述

  Oracle 學習之性能優(yōu)化(二)游標

還記得我們在http://lqding.blog.51cto.com/9123978/1685341這篇文章中描述的硬解析、軟解析嗎?

硬解析,上圖中的第4種情況,需要重新構造一個游標。

軟解析,上圖中的第3種情況,可以在共享池中查詢到可以被重用的游標信息。

軟軟解析:如上圖,不單Shared pool中有cursor的詳細信息,UGA中也會記錄cursor的狀態(tài)。當一個sql  發(fā)出后,如果能在uga中找到已經(jīng)打開的相同游標,那么直接共用該游標。無需再進行Shared pool檢  查。如果uga中的cursor已經(jīng)關閉,那么直接打開游標即可。也可以直接共用游標。這兩種情況都無  需進行Shared pool的檢查,這種解析稱之為軟軟解析。

Session Cursor

 使用v$open_cursor視圖查詢,一個會話最多可以打開的游標數(shù)由參數(shù)OPEN_CURSORS定義。

 session cursor又分為三種:分別是implicit cursor,explicit cursor和ref cursor。

共享游標分類:

  • 父游標

    文本相同的子游標的代表。所有文本相同的SQL都共享父游標。

    父游標沒有執(zhí)行計劃,只有一些管理性的信息,包含了SQL TEXT和相關的hash value等。

    v$sqlarea中的每一行代表了一個parent cursor, address字段表示其內(nèi)存地址。

  • 子游標

    SQL文本相同,但是因執(zhí)行環(huán)境等不同,會生成多個執(zhí)行計劃。

    包含了SQL的metadata,即使得這個SQL可以執(zhí)行的所有相關信息,如OBJECT和權限,優(yōu)化器設置,執(zhí)行計劃等。v$sql中的每一行表示了一個child cursor,根據(jù)hash value和address與parent cursor 關聯(lián)。child cursor有自己的address,即V$SQL.CHILD_ADDRESS。

案例:

1. 創(chuàng)建一個用戶

SQL> conn / as sysdba Connected. SQL> create user ding identified by ding; User created. SQL> grant resource,connect to ding; Grant succeeded.

2. 生成數(shù)據(jù)

SQL> create table ding.emp as select * from scott.emp; Table created.

將數(shù)據(jù)庫重啟

3. 分別登錄scott和ding用戶,執(zhí)行如下查詢

SQL> select * from emp;

4. 查看父游標

SQL> COL SQL_TEXT FOR A30 SQL> COL SQL_ID FOR A20 SQL> SET LINESIZE 200 SQL> SELECT sql_text,        sql_id,        EXECUTIONS,        LOADS,        VERSION_COUNT   FROM v$sqlarea  WHERE sql_text LIKE '%emp'; SQL_TEXT        SQL_ID     EXECUTIONS     LOADS VERSION_COUNT ------------------------------ -------------------- ---------- ---------- ------------- select * from emp        a2dk8bdn0ujx7      2 2       2

兩次查詢共享了一個父游標,該父游標被load 2次,表示被硬解析了兩次。VERSION_COUNT表示子游標的個數(shù)。

5. 查看子游標

SQL>  SELECT sql_id,sql_text,loads,child_number,parse_calls   FROM v$sql  WHERE sql_text LIKE '%emp'; SQL_ID      SQL_TEXT  LOADS CHILD_NUMBER PARSE_CALLS -------------------- ------------------------------ ---------- ------------ ----------- a2dk8bdn0ujx7      select * from emp      1   0       1 a2dk8bdn0ujx7      select * from emp      1   1       1

6. scott用戶下的語句再執(zhí)行一遍,再次查看父子游標

SQL> SELECT sql_text,        sql_id,        EXECUTIONS,        LOADS,        VERSION_COUNT   FROM v$sqlarea  WHERE sql_text LIKE '%emp';  2    3    4    5    6    7   SQL_TEXT        SQL_ID     EXECUTIONS     LOADS VERSION_COUNT ------------------------------ -------------------- ---------- ---------- ------------- select * from emp        a2dk8bdn0ujx7      3 2       2

EXECUTIONS變成了3.

SQL> SELECT sql_id,        sql_text,        loads,        child_number,        parse_calls,        parsing_schema_name   FROM v$sql  WHERE sql_text LIKE '%emp'  2    3    4    5    6    7    8  ; SQL_ID      SQL_TEXT  LOADS CHILD_NUMBER PARSE_CALLS PARSING_SC -------------------- ------------------------------ ---------- ------------ ----------- ---------- a2dk8bdn0ujx7      select * from emp      1   0       1 DING a2dk8bdn0ujx7      select * from emp      1   1       2 SCOTT

只有文本完全相同,才能共享父游標。哪怕是語句的語義、環(huán)境等有完全相同,sql文本稍微不同都不行。例如如下sql

select * from emp; select  * from emp; select * from Emp;

那么當父游標相同,有多個子游標時,我們?nèi)绾沃朗呛卧驅(qū)е虏还蚕碜佑螛四兀?/p>SELECT *   FROM v$sql_shared_cursor  WHERE sql_id = 'a2dk8bdn0ujx7'

 這個表中會有什么*MISMATCH的字段,如果該值為Y,就表示是因為這個字段指示的內(nèi)容不一致導致不能共享子游標。

游標的生命周期:

(1)打開游標(dbms_sql.open_cursor)

  Open cursor: A memory structure for the cursor is allocated in the server-side private memory of the server process associated with the session, the user global area (UGA). Note that no SQL statement isassociated with the cursor yet.

 系統(tǒng)會在UGA中分配相關的內(nèi)存結構,就是獲得游標句柄的過程,這時的游標還未和sql語句有關聯(lián);

(2)解析游標(dbms_sql.parse)

  Parse cursor: A SQL statement is associated with the cursor. Its parsed representation that includes the execution plan (which describes how the SQL engine will execute the SQL statement) is loaded in the shared pool, specifically, in the library cache. The structure in the UGA is updated to store a pointer to the location of the shareable cursor in the library cache. The next section will describe parsing in more detail.

  有一條sql與游標相關聯(lián),并將執(zhí)行解析過后的執(zhí)行計劃放在library cache(SGA的shared pool下)中,UGA中生成指向這個共享游標的指針;即session cursor 指向shared cursor。 一個session cursor 只能指向一個shared cursor,而一個shared cursor 可以指向多個session cursor。
(3)定義輸出變量(dbms_sql.define_column)

  Define output variables: If the SQL statement returns data, the variables receiving it must be defined. This is necessary not only for queries but also for DELETE, INSERT, and UPDATE statements that use the RETURNING clause.

  如果sql語句返回數(shù)據(jù),必須定義接收數(shù)據(jù)的變量,對delete,update,insert來說是returning;

(4)綁定輸入變量(dbms_sql.bind_variable/bind_array)

  Bind input variables: If the SQL statement uses bind variables, their values must be provided. No check is performed during the binding. If invalid data is passed, a runtime error will be raised during the execution.

  綁定過程是不做檢查的;
(5)執(zhí)行游標(dbms_sql.execute)

  Execute cursor: The SQL statement is executed. But becareful, because the database engine doesn’t always do anything significant during this phase. In fact, for many types of queries, the real processing isusually delayed to the fetch phase.

  這步數(shù)據(jù)庫引擎其實不做什么重要事情,而對大多數(shù)sql語句來說,真正處理過程是到fetch獲取數(shù)據(jù)階段;
(6)獲取游標(dbms_sql.fetch_rows)

  Fetch cursor: If the SQL statement returns data, this step retrieves it. Especially for queries, this step is where most of theprocessing is performed. In the case of queries, rows might be partiallyfetched. In other words, the cursor might be closed before fetching all therows.

  真正的處理過程,有返回數(shù)據(jù)的話,必須提供輸出變量(dbms_sql.column_value);
(7)關閉游標(dbms_sql.close_cursor)

  Close cursor: The resources associated with the cursorin the UGA are freed and consequently made available for other cursors. The shareable cursor in the library cache is not removed. It remains there in the hope of being reused in the future.

  釋放UGA中相關資源,庫緩存中共享游標不會被清除。

  當游標被關閉后,還可以繼續(xù)緩存在內(nèi)存中,參數(shù)SESSION_CACHED_CURSORS定義當前Session已經(jīng)關閉并被緩存的游標的大數(shù)量,即單個session中同時能cache住的soft closed session cursor的大數(shù)量。

另外有需要云服務器可以了解下創(chuàng)新互聯(lián)cdcxhl.cn,海內(nèi)外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。

文章標題:Oracle學習之性能優(yōu)化(二)游標-創(chuàng)新互聯(lián)
瀏覽路徑:http://muchs.cn/article38/dhepsp.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設計、營銷型網(wǎng)站建設建站公司、網(wǎng)站設計公司、網(wǎng)站收錄、企業(yè)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設計