真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Oracle性能優(yōu)化之游標(biāo)及SQL-創(chuàng)新互聯(lián)

一、游標(biāo)

創(chuàng)新互聯(lián)是一家專注網(wǎng)站建設(shè)、網(wǎng)絡(luò)營(yíng)銷策劃、成都小程序開發(fā)、電子商務(wù)建設(shè)、網(wǎng)絡(luò)推廣、移動(dòng)互聯(lián)開發(fā)、研究、服務(wù)為一體的技術(shù)型公司。公司成立10多年以來,已經(jīng)為近千家三維植被網(wǎng)各業(yè)的企業(yè)公司提供互聯(lián)網(wǎng)服務(wù)?,F(xiàn)在,服務(wù)的近千家客戶與我們一路同行,見證我們的成長(zhǎng);未來,我們一起分享成功的喜悅。

我們要先說一下游標(biāo)這個(gè)概念。

     

從 Oracle 數(shù)據(jù)庫(kù)管理員的角度上說,游標(biāo)是對(duì)存儲(chǔ)在庫(kù)緩存中的可執(zhí)行對(duì)象的統(tǒng)稱。SQL 語句是存儲(chǔ)在庫(kù)緩存中的,它是游標(biāo)。除了它之外,還有 Oracle 的存儲(chǔ)過程也是存儲(chǔ)在庫(kù)緩存中的可執(zhí)行對(duì)象,從 Oracle DBA 的角度上說,它也是游標(biāo)。Oracle 也把它算為游標(biāo),在某些和游標(biāo)相關(guān)的視圖中,也會(huì)顯示存儲(chǔ)過程的一些信息的。但從開發(fā)者的角度說,只有 SQL 語句才是游標(biāo)。

二、關(guān)于游標(biāo)的視圖

你的應(yīng)用程序或許是用 Java、Pro*C 等語言開發(fā)的,也可能有中件間,等等,對(duì)于 DBA 來說,我們不必過多的關(guān)心這些。以一個(gè)常見的三層應(yīng)用為例, 如下圖:

Oracle 性能優(yōu)化 之 游標(biāo)及 SQL


類似的圖我們?cè)诤芏嗟胤蕉伎梢钥吹剑僭O(shè)這是一個(gè)三層 J2EE 應(yīng)用。客戶端調(diào)用的 Java 應(yīng)用程序存放在中間的應(yīng)用服務(wù)器層,應(yīng)用程序的執(zhí)行由應(yīng)用服務(wù)器負(fù)責(zé)。


如上圖這段 Java 應(yīng)用程序,它的執(zhí)行就是應(yīng)用應(yīng)用服務(wù)器的任務(wù)。但是,當(dāng)執(zhí)行到 executeQuery ("select * from Test") 語句時(shí),這條 Java 語句要求從數(shù)據(jù)庫(kù)服務(wù)器中查詢表 Test。發(fā)下圖:


這條語句的執(zhí)行,是由數(shù)據(jù)庫(kù)服務(wù)器負(fù)責(zé)的。數(shù)據(jù)庫(kù)服務(wù)器只負(fù)責(zé)以最快的速度將 “Select * from test” 執(zhí)行完畢。其他的它一概不負(fù)責(zé)。我們作為 DBA,只要保證 SQL 語句可以更快的執(zhí)行就行了,至于應(yīng)用程序邏輯方面的問題,不由我們負(fù)責(zé)。也就是說,作為 DBA,我們不必負(fù)責(zé)具體代碼的問題,我們只負(fù)責(zé) SQL 語句的執(zhí)行。每條送交 Oracle 執(zhí)行的 SQL 語句,無論這條語句是你手動(dòng)在 SQL*Plus 命令窗口中敲入的,還是應(yīng)用服務(wù)器傳送給 Oracle 要求執(zhí)行的,它們都以一樣的方式被傳遞到 Oracle 中,由服務(wù)器進(jìn)程執(zhí)行。這些 SQL 語句的執(zhí)行情況、具體的執(zhí)行計(jì)劃等數(shù)據(jù)資料會(huì)在一些視圖中被記錄下來,以供 DBA 追蹤問題、調(diào)優(yōu) SQL 的執(zhí)行。


下面,我們就介紹一下這些相關(guān) SQL 執(zhí)行情況的視圖。我們?cè)購(gòu)?qiáng)調(diào)一個(gè)名詞,對(duì)于從任何地方傳遞給 Oracle 數(shù)據(jù)庫(kù)服務(wù)器要求執(zhí)行的東西,我們都稱為游標(biāo)。它主要包括 SQL 語句和 PL/SQL 程序段。


1. V$SQL

SQL_TEXT:SQL 語句的文本

SQL_FULLTEXT:SQL 語句的完全文本

SQL_ID


SHARABLE_MEM:游標(biāo)所占共享內(nèi)存


PERSISTENT_MEM:游標(biāo)持續(xù)期所占用的 Fixed(固定)內(nèi)存

 

RUNTIME_MEM:游標(biāo)在運(yùn)行期所占用的 Fixed(固定)內(nèi)存


SORTS:游標(biāo)完成的排序次數(shù)

LOADED_VERSIONS:游標(biāo)在庫(kù)緩存所占的內(nèi)存堆是否被加載

OPEN_VERSIONS:游標(biāo)是否被鎖定。

USERS_OPENING:打開游標(biāo)的會(huì)話數(shù)。也就是當(dāng)正在緩存游標(biāo)到 PGA 中的會(huì)話數(shù)。游標(biāo)被執(zhí)行三次后,就會(huì)被緩存到 PGA 中。此數(shù)值就加 1。


FETCHES:抓取的次數(shù)

EXECUTIONS:執(zhí)行次數(shù)

PX_SERVERS_EXECUTIONS:以并行方式執(zhí)行的總次數(shù)

END_OF_FETCH_COUNT:抓取全部行的次數(shù)

USERS_EXECUTING:當(dāng)前正在執(zhí)行此游標(biāo)的會(huì)話數(shù)


LOADS:游標(biāo)被加載或重新加載到庫(kù)緩存中的次數(shù)。游標(biāo)只所以被重新加載有可能是游標(biāo)無效或庫(kù)緩存內(nèi)存不足。


FIRST_LOAD_TIME:游標(biāo)被第一次被加載的時(shí)間。也就是生成執(zhí)行計(jì)劃的時(shí)間


INVALIDATIONS:游標(biāo)的無效次數(shù)

PARSE_CALLS:游標(biāo)的解析次數(shù),包括硬解析與軟解析

DISK_READS:游標(biāo)執(zhí)行了多少次物理讀

DIRECT_WRITES:游標(biāo)直接寫的次數(shù)

BUFFER_GETS:邏輯讀的次數(shù)

 

APPLICATION_WAIT_TIME:應(yīng)用程序的等待時(shí)間,單位微秒

 

CONCURRENCY_WAIT_TIME:并行的等待時(shí)間,單位微秒

 

CLUSTER_WAIT_TIME:Cluster 等待時(shí)間

 

USER_IO_WAIT_TIME:用戶 I/O 等待時(shí)間

 

PLSQL_EXEC_TIME:PL/SQL 執(zhí)行時(shí)間

 

JAVA_EXEC_TIME:Java 執(zhí)行時(shí)間

 

ROWS_PROCESSED:游標(biāo)一共抓取了多少行。同樣的行,每抓取一次此列都會(huì)增加

 

COMMAND_TYPE:命令類型

 

OPTIMIZER_MODE:優(yōu)化器模式

 

OPTIMIZER_COST:執(zhí)行計(jì)劃的成本

 

OPTIMIZER_ENV:執(zhí)行時(shí)的環(huán)境

 

OPTIMIZER_ENV_HASH_VALUE:環(huán)境的 HASH 值

 

PARSING_USER_ID:最先解析此游標(biāo)的用戶的 ID

 

PARSING_SCHEMA_ID:最先解析此游標(biāo)的方案 ID

PARSING_SCHEMA_NAME:最先解析此游標(biāo)的方案 ID

KEPT_VERSIONS:是否使用 DBMS_SHARED_POOL 包將游標(biāo) Pin 到庫(kù)緩存中

 

ADDRESS:父游標(biāo)句柄的地址

 

TYPE_CHK_HEAP:

 

HASH_VALUE:游標(biāo)的 HASH 值

 

OLD_HASH_VALUE:老 HASH 值

 

PLAN_HASH_VALUE:執(zhí)行計(jì)劃的 HASH 值。(上述三個(gè) HASH 值并不相同)

 

CHILD_NUMBER:子游標(biāo)數(shù)量

 

SERVICE:

 

SERVICE_HASH

 

MODULE:第一次解析游標(biāo)的應(yīng)用程序名??梢栽趹?yīng)用程序中通過調(diào)用 DBMS_APPLICATION_INFO.SET_MODULE 設(shè)置。

 

MODULE_HASH:應(yīng)用程序名的 HASH 值

 

ACTION:第一次解析時(shí)的動(dòng)作名??梢栽趹?yīng)用程序中通過調(diào)用 DBMS_APPLICATION_INFO.SET_ACTION 設(shè)置。

 

ACTION_HASH:動(dòng)作名的 HASh 值

 

SERIALIZABLE_ABORTS:每個(gè)游標(biāo)產(chǎn)生 ORA-08177 errors 錯(cuò)誤(事務(wù)串行化無效)的次數(shù)。

 

OUTLINE_CATEGORY:大綱類型

 

CPU_TIME:游標(biāo)解析、執(zhí)行、抓取時(shí)所用的 CPU 時(shí)間。單位是微秒。

ELAPSED_TIME:游標(biāo)解析、執(zhí)行、抓取時(shí)所用的總時(shí)間。單位是微秒。

 

OUTLINE_SID:大綱會(huì)話的 SID

 

CHILD_ADDRESS:游標(biāo)本身的地址

 

SQLTYPE:游標(biāo)所用的 SQL 語言的版本

 

REMOTE:游標(biāo)是否是遠(yuǎn)端映像的

 

OBJECT_STATUS:對(duì)象狀態(tài)

 

LITERAL_HASH_VALUE:游標(biāo)文本的 HASH 值

 

LAST_LOAD_TIME:執(zhí)行計(jì)劃最后一次被加載到庫(kù)緩存中的時(shí)間。

 

IS_OBSOLETE:當(dāng)子游標(biāo)太多時(shí),此子游標(biāo)是否被荒廢。

 

CHILD_LATCH:保護(hù)游標(biāo)的子閂編號(hào)

 

SQL_PROFILE:SQL 的概要文件

 

PROGRAM_ID:過程 ID

 

PROGRAM_LINE#

 

EXACT_MATCHING_SIGNATURE

 

FORCE_MATCHING_SIGNATURE

 

LAST_ACTIVE_TIME:最后一次使用執(zhí)行計(jì)劃的時(shí)間。

 

BIND_DATA:綁定變量的信息


這個(gè)視圖中 DISK_READS、BUFFER_GETS、CPU_TIME、ELAPSED_TIME 這四個(gè)列在調(diào)優(yōu) SQL 語句時(shí)最為重要。在數(shù)據(jù)庫(kù)系統(tǒng)的速度不是太另人滿意時(shí),如果你已經(jīng)確定過了,不是其他方面的原因,而是 SQL 語句性能的問題,只是無法確定是那條、或那些條語句拖慢了整體的速度。那么此時(shí)選擇調(diào)優(yōu)物理讀、邏輯讀最多的,或最耗 CPU 時(shí)間的 SQL 語句進(jìn)行調(diào)節(jié),往往可以取得今人滿意的性能增長(zhǎng)。

     

我們也可以以 EXECUTIONS(執(zhí)行次數(shù))最多的 SQL 語句為調(diào)優(yōu)對(duì)象。另外,PARSE_CALLS 是解析次數(shù),對(duì)于此列值最多的 SQL 語句,我們可以看看是否可以降低語句的解析次數(shù)。

     

關(guān)于 SQL 調(diào)優(yōu),和程序的調(diào)優(yōu)是一樣的。如果我們從事過代碼優(yōu)化這樣的工作,就會(huì)知道,對(duì)于一個(gè)大型的應(yīng)用程序來說調(diào)優(yōu)的方法也是要從執(zhí)行次數(shù)最多的那部分代碼、或從最消耗資源的代碼入手。

     

還有一個(gè)問題,就是文檔中關(guān)于這個(gè)視圖會(huì)經(jīng)常提到一個(gè)概念:子游標(biāo)與父游標(biāo)。如果兩個(gè)游標(biāo)的文本一模一樣,但由于環(huán)境不同,比如,游標(biāo)所操作的表是不同用戶下的同名表,這兩個(gè)游標(biāo)是不能共享執(zhí)行計(jì)劃的。它們都有各自的執(zhí)行計(jì)劃存在庫(kù)緩存中。這兩個(gè)游標(biāo)就是子游標(biāo),Oracle 還會(huì)建立一個(gè)父游標(biāo),父游標(biāo)中沒有執(zhí)行計(jì)劃,它只是文本相同但執(zhí)行計(jì)劃不同的所有游標(biāo)的代表。

     

其實(shí)在庫(kù)緩存中,即使沒有文本相同的子游標(biāo),Oracle 會(huì)為每個(gè)游標(biāo)都創(chuàng)建父游標(biāo)。因?yàn)楦赣螛?biāo)是文本相同的子游標(biāo)的代表嗎,所有文本相同的游標(biāo)共享同一個(gè)父游標(biāo)。

     

也就是說,只要你執(zhí)行 SQL 語句,Oracle 都會(huì)在庫(kù)緩存中保存一父一子兩個(gè)游標(biāo)。如果你執(zhí)行了文本相同但環(huán)境不同因而不能共享執(zhí)行計(jì)劃的 SQL 語句,那么一個(gè)父游標(biāo)可能就對(duì)應(yīng)多個(gè)子游標(biāo)。

     

父游標(biāo)沒有執(zhí)行計(jì)劃,它只有一信息管理性數(shù)據(jù),Oracle 添加它的目的就是為了管理文本相同的游標(biāo)。有一個(gè)視圖是專門針對(duì)父游標(biāo)的,就是 V$sqlarea。下面我們說一下這個(gè)視圖。


2. V$SQLAREA

V$SQLAREA 和 V$SQL 的列幾乎是一模一樣的。在 V$SQLAREA 中匯總了子游標(biāo)的數(shù)據(jù)。如果有兩個(gè)語句:語句 A 和語句 B,它們文本一模一樣,但是由于環(huán)境不同沒有共享執(zhí)行計(jì)劃,而是有各自的執(zhí)行計(jì)劃。也就是語句 A 和語句 B 是同一父游標(biāo)下的子游標(biāo)。在 V$SQL 視圖中,因?yàn)樗秋@示子游標(biāo)的,所以語句 A 和語句 B 各占一行,假設(shè)語句 A 的 DISK_READS(物理讀)是 100,語句 B 的物理讀是 3000。V$SQLAREA 是顯示父游標(biāo)信息的,語句 A 和語句 B 因?yàn)槲谋鞠嗤鼈儍蓚€(gè)對(duì)應(yīng)同一個(gè)父游標(biāo),在 V$SQLAREA 中占一行。在 V$SQLAREA 中,語句 A 和語句 B 父游標(biāo)行中的 DISK_READS 就是 3100,也就是語句 A 和語句 B 的和。V$SQLAREA 中的其它列也是如此,都是 V$SQL 中相應(yīng)子游標(biāo)的合計(jì)。

     

有一個(gè)列是 V$SQL 中沒有的,就是:VERSION_COUNT,它是對(duì)應(yīng)同一父游標(biāo)的子游標(biāo)的數(shù)量。如果這個(gè)數(shù)字太高,可能代表由于某些原因使本可以共享執(zhí)行計(jì)劃的游標(biāo)沒有共享。


3.V$open_cursor 與 Open_cursor 參數(shù)

這個(gè)視圖和參數(shù)涉及游標(biāo)的打開。什么是游標(biāo)的打開,就是在庫(kù)緩存中,用戶在軟、硬解析游標(biāo)時(shí),會(huì)在游標(biāo)對(duì)象的句柄上加一個(gè)鎖,也就是 Library cache lock。在解析并執(zhí)行完游標(biāo)后,這個(gè)鎖并不會(huì)馬上去掉,而是會(huì)一直保留著,直到用戶發(fā)出了 Close 命令關(guān)閉游標(biāo)時(shí)為止。我們?cè)?SQL*Plus 命令窗口中發(fā)出的命令,在抓取完所有行后,SQL*Plus 將自動(dòng)為我們發(fā)出 Close 命令來關(guān)閉游標(biāo)。

 

當(dāng)游標(biāo)打開時(shí),Library cache lock 將一直保持,這樣,即使庫(kù)緩存內(nèi)存緊張,需要老化對(duì)象,也不會(huì)老化這些還正在加鎖的對(duì)象。因此,如果用戶不停的要求數(shù)據(jù)庫(kù)服務(wù)器打開游標(biāo)、執(zhí)行 SQL,但卻忘了關(guān)閉游標(biāo),這很容易耗盡共享池的內(nèi)存。為此,Oracle 準(zhǔn)備了一個(gè)參數(shù),就是 Open_cursor,它的默認(rèn)值在 9i 下是 50,在 10g 中是 300,也就是說,在 10g 下,每個(gè)會(huì)話最多只能同時(shí)打開 300 個(gè)游標(biāo)。有了這個(gè)限制,就不用害怕用戶不停的打開游標(biāo)但又不關(guān)閉它,而耗盡共享池內(nèi)存了。

     

如果會(huì)話同時(shí)打開的游標(biāo)數(shù)量超出了 Open_cursor 參數(shù)的限制,Oracle 將禁止會(huì)話打開新的游標(biāo)。同時(shí)報(bào)出錯(cuò)誤:ORA-01000: 超出打開游標(biāo)的大數(shù) 。

     

在用戶斷開會(huì)話的連接后,會(huì)話打開的這些游標(biāo)將自動(dòng)關(guān)閉。

     

V$open_cursor 視圖專用來查看當(dāng)前會(huì)話打開的游標(biāo)信息。它只能查看當(dāng)前會(huì)話打開的游標(biāo)。


4.CURSOR_SHARING 參數(shù)

如果應(yīng)用程序中有很多類似下面這樣的 SQL 語句:


select * from 某表 where id=1;

select * from 某表 where id=2;

select * from 某表 where id=50;

     

等等,這些 SQL 語句嚴(yán)格來說是無法共享游標(biāo)(也就是共享執(zhí)行計(jì)劃)的,但是這些語句所需要執(zhí)行計(jì)劃其實(shí)都是一樣的。無論你在表中查詢 ID 為 1 的行還是查詢 ID 為 100 的行,執(zhí)行方式應(yīng)該是一樣的。如果你想讓這樣的語句共享游標(biāo),那么,你可以改變 Cursor_sharing 參數(shù)的值。


此參有三個(gè)值:

  • ? EXACT:這個(gè)值是默認(rèn)值。除非游標(biāo)文本一模一樣,否則不會(huì)共享游標(biāo)。

  • ? SIMILAR:這個(gè)最智能,如果游標(biāo)只有條件中的數(shù)據(jù)值部分不同,并且?guī)炀彺嬷性杏螛?biāo)的執(zhí)行計(jì)劃對(duì)于新執(zhí)行的 SQL 語句也是最優(yōu)的,將不再為 SQL 語句創(chuàng)建新的游標(biāo),而是讓它共享庫(kù)緩存中原有的游標(biāo)。

  • ? FORCE :不比較執(zhí)行計(jì)劃是否最優(yōu),只要游標(biāo)中除了條件中的數(shù)據(jù)值部分不同外,其他部分都相同,就會(huì)共享游標(biāo)。

     

此參數(shù)可以在會(huì)話級(jí)修改,也就是可以使用 Alter session 修改它的值,這將只影響某一個(gè)會(huì)話,而不會(huì)影響其他會(huì)話。


網(wǎng)頁(yè)名稱:Oracle性能優(yōu)化之游標(biāo)及SQL-創(chuàng)新互聯(lián)
網(wǎng)站鏈接:http://weahome.cn/article/dgshpg.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部