1. SGA的設(shè)置
在Oracle Tuning中,對(duì)SGA的設(shè)置是關(guān)鍵。SGA,是指Shared Global Area , 或者是 System Global Area , 稱為共享全局區(qū)或者系統(tǒng)全局區(qū),結(jié)構(gòu)如下圖所示。
對(duì)于SGA區(qū)域內(nèi)的內(nèi)存來(lái)說(shuō),是共享的、全局的,在UNIX 上,必須為oracle 設(shè)置共享內(nèi)存段(可以是一個(gè)或者多個(gè)),因?yàn)閛racle 在UNIX上是多進(jìn)程;而在WINDOWS上oracle是單進(jìn)程(多個(gè)線程),所以不用設(shè)置共享內(nèi)存段。
1.1 SGA的各個(gè)組成部分
下面用 sqlplus 查詢舉例看一下 SGA 各個(gè)組成部分的情況:
SQL> select * from v$sga;
NAME VALUE
-------------------- ----------
Fixed Size 104936
Variable Size 823164928
Database Buffers 1073741824
Redo Buffers 172032
或者
SQL> show sga
Total System Global Area 1897183720 bytes
Fixed Size 104936 bytes
Variable Size 823164928 bytes
Database Buffers 1073741824 bytes
Redo Buffers 172032 bytes
Fixed Size
oracle 的不同平臺(tái)和不同版本下可能不一樣,但對(duì)于確定環(huán)境是一個(gè)固定的值,里面存儲(chǔ)了SGA 各部分組件的信息,可以看作引導(dǎo)建立SGA的區(qū)域。
Variable Size
包含了shared_pool_size、java_pool_size、large_pool_size 等內(nèi)存設(shè)置
Database Buffers
指數(shù)據(jù)緩沖區(qū),在8i 中包含db_block_buffer*db_block_size、buffer_pool_keep、buffer_pool_recycle 三部分內(nèi)存。在9i 中包含db_cache_size、db_keep_cache_size、db_recycle_cache_size、db_nk_cache_size。
Redo Buffers
指日志緩沖區(qū),log_buffer。在這里要額外說(shuō)明一點(diǎn)的是,對(duì)于v$parameter、v$sgastat、v$sga查詢值可能不一樣。v$parameter 里面的值,是指用戶在初始化參數(shù)文件里面設(shè)置的值,v$sgastat是oracle 實(shí)際分配的日志緩沖區(qū)大�。ㄒ�?yàn)榫彌_區(qū)的分配值實(shí)際上是離散的,也不是以block 為最小單位進(jìn)行分配的),v$sga 里面查詢的值,是在oracle 分配了日志緩沖區(qū)后,為了保護(hù)日志緩沖區(qū),設(shè)置了一些保護(hù)頁(yè),通常我們會(huì)發(fā)現(xiàn)保護(hù)頁(yè)大小是8k(不同環(huán)境可能不一樣)。參考如下內(nèi)容
SQL> select substr(name,1,10) name,substr(value,1,10) value
2 from v$parameter where name = 'log_buffer';
NAME VALUE
-------------------- --------------------
log_buffer 163840
SQL> select * from v$sgastat where pool is null;
POOL NAME BYTES
----------- -------------------------- ----------
fixed_sga 104936
db_block_buffers 1073741824
log_buffer 163840
SQL> select * from v$sga;
NAME VALUE
-------------------- ----------
Fixed Size 104936
Variable Size 823164928
Database Buffers 1073741824
Redo Buffers 172032
172032 – 163840 = 8192
(以上試驗(yàn)數(shù)據(jù)是在 HP B.11.11 + Oracle 8.1.7.4 環(huán)境下得到的)
1.2 SGA的大小設(shè)置
在對(duì)SGA的結(jié)構(gòu)進(jìn)行簡(jiǎn)單分析以后,下面是關(guān)于如何根據(jù)系統(tǒng)的情況正確設(shè)置SGA大小的問(wèn)題。
SGA是一塊內(nèi)存區(qū)域,占用的是系統(tǒng)物理內(nèi)存,因此對(duì)于一個(gè)Oracle應(yīng)用系統(tǒng)來(lái)說(shuō),SGA決不是越大越好,這就需要尋找一個(gè)系統(tǒng)優(yōu)化的平衡點(diǎn)。
1.2.1 設(shè)置參數(shù)前的準(zhǔn)備
在設(shè)置SGA的內(nèi)存參數(shù)之前,我們首先要問(wèn)自己幾個(gè)問(wèn)題
一:物理內(nèi)存多大
二:操作系統(tǒng)估計(jì)需要使用多少內(nèi)存
三:數(shù)據(jù)庫(kù)是使用文件系統(tǒng)還是裸設(shè)備
四:有多少并發(fā)連接
五:應(yīng)用是OLTP 類型還是OLAP 類型
根據(jù)這幾個(gè)問(wèn)題的答案,我們可以粗略地為系統(tǒng)估計(jì)一下內(nèi)存設(shè)置。那我們現(xiàn)在來(lái)逐個(gè)問(wèn)題地討論,首先物理內(nèi)存多大是最容易回答的一個(gè)問(wèn)題,然后操作系統(tǒng)估計(jì)使用多少內(nèi)存呢?從經(jīng)驗(yàn)上看,不會(huì)太多,通常應(yīng)該在200M 以內(nèi)(不包含大量進(jìn)程PCB)。
接下來(lái)我們要探討一個(gè)重要的問(wèn)題,那就是關(guān)于文件系統(tǒng)和裸設(shè)備的問(wèn)題,這往往容易被我們所忽略。操作系統(tǒng)對(duì)于文件系統(tǒng),使用了大量的buffer 來(lái)緩存操作系統(tǒng)塊。這樣當(dāng)數(shù)據(jù)庫(kù)獲取數(shù)據(jù)塊的時(shí)候,雖然SGA 中沒(méi)有命中,但卻實(shí)際上可能是從操作系統(tǒng)的文件緩存中獲取的。而假如數(shù)據(jù)庫(kù)和操作系統(tǒng)支持異步IO,則實(shí)際上當(dāng)數(shù)據(jù)庫(kù)寫進(jìn)程DBWR寫磁盤時(shí),操作系統(tǒng)在文件緩存中標(biāo)記該塊為延遲寫,等到真正地寫入磁盤之后,操作系統(tǒng)才通知DBWR寫磁盤完成。對(duì)于這部分文件緩存,所需要的內(nèi)存可能比較大,作為保守的估計(jì),我們應(yīng)該考慮在 0.2——0.3 倍內(nèi)存大小。但是如果我們使用的是裸設(shè)備,則不考慮這部分緩存的問(wèn)題。這樣的情況下SGA就有調(diào)大的機(jī)會(huì)。
關(guān)于數(shù)據(jù)庫(kù)有多少并發(fā)連接,這實(shí)際上關(guān)系到PGA 的大�。∕TS 下還有l(wèi)arge_pool_size)。事實(shí)上這個(gè)問(wèn)題應(yīng)該說(shuō)還跟OLTP 類型或者OLAP 類型相關(guān)。對(duì)于OLTP類型oracle 傾向于可使用MTS,對(duì)于OLAP 類型使用獨(dú)立模式,同時(shí)OLAP 還可能涉及到大量的排序操作的查詢,這些都影響到我們內(nèi)存的使用。那么所有的問(wèn)題綜合起來(lái),實(shí)際上主要反映在UGA的大小上。UGA主要包含以下部分內(nèi)存設(shè)置
SQL> show parameters area_size
NAME TYPE VALUE
------------------------------------ ------- --------
bitmap_merge_area_size integer 1048576
create_bitmap_area_size integer 8388608
hash_area_size integer 131072
sort_area_size integer 65536
SQL>
文件中描述了2個(gè)導(dǎo)入工作:(1)表EMPLOYEE_TEST(2)表YFJBXX_TEST,文件中每張表的列名和類型需要和導(dǎo)入的目標(biāo)表一致,且順序和文件中要導(dǎo)入的內(nèi)容相匹配,例如下面的csv文件:
"ID","DEP","NAME","AREA","AGE","SEX","XUELI","SALARY","PRIX"
"001","研發(fā)","張三","北京","34","女","本科","4546","1"
"002","銷售","李四","天津","45","男","專科","4456","2"
可以看到導(dǎo)入的順序和上述XML文件中的列名一致。
如果從文件導(dǎo)入到數(shù)據(jù)庫(kù)中完全匹配,只需配置文件中的<Bean name="ImportDirectImpl" class="fileimport.ImportDirectImpl"/>即可,代碼中調(diào)用示例:
//設(shè)置XML配置文件所在位置
FileImportInitFactory.setConfigFileName("E:/EclipseProjects/WISImport/bin/fileimport/FileImportConfig.xml");
&nb
sp; FileImportInitFactory.init();
HashMap h = new HashMap(1,1);
//如果有日期型的列,需要設(shè)置DateFormat并放入HashMap中
h.put("DateFormat","yyyy-MM-dd HH:mm:ss");
//執(zhí)行導(dǎo)入工作
new ImportFileEntry().importFile("導(dǎo)入的文件路徑及名稱.csv","YFJBXX_TEST",false,"ImportDirectImpl",h);
ImportFileEntry()的importFile方法說(shuō)明:
/**
* 從文件導(dǎo)入到指定表中
* @param fileName String 要導(dǎo)入文件名
* @param tableName String 導(dǎo)入目標(biāo)表名
* @param firstLineRead boolean 是否讀取第一行
* @param dealClass 處理類名稱(例如配置文件中Bean name="ImportDirectImpl")
* @param aHashMap 擴(kuò)展用,需特殊處理時(shí)可置入變量
* @throws Exception
*/
public void importFile(String fileName, String tableName, boolean firstLineRead,String dealClass,HashMap aHashMap) throws Exception ;
至此,一個(gè)簡(jiǎn)單的不需做任何處理直接從文件導(dǎo)入數(shù)據(jù)庫(kù)對(duì)應(yīng)表的功能就實(shí)現(xiàn)了。
但是有些時(shí)候我們需要進(jìn)行特殊的處理,例如表中的當(dāng)前操作日期列在導(dǎo)入文件中沒(méi)有,需要在代碼中加入,這時(shí)就需要實(shí)現(xiàn)FileImportInterface接口并加入到配置文件中例如:<Bean name="ImportWISImpl" class="fileimport.ImportWISImpl"/>,ImportWISImpl的實(shí)現(xiàn)代碼見(jiàn)后續(xù)代碼清單。
t;);
columnListInfoCode[i][0] = columnName;
columnListInfoCode[i][1] = columnType;
System.out.println("Code columnName:" + columnName + " columnType:" + columnType);
}
}
//生成實(shí)例
ImportTableInfoBO importAction = new ImportTableInfoBO();
importAction.setTableName(tableName);
importAction.setColumnNamesFile(columnListInfoFile);
if (columnListInfoCode != null) {
importAction.setColumnNamesCode(columnListInfoCode);
}
//放入靜態(tài)容器中
importJobList.put(tableName, importAction);
}
//2.其他配置信息
Element importDealClassList = (Element) eroot.getElementsByTagName("ImportDealClassList").item(0);
String className;
String classFullName;
NodeList beanList = importDealClassList.getElementsByTagName("Bean");
for (int j=0; j < beanList.getLength(); j++){
className = ( (Element) beanList.item(j)).getAttribute("name");
classFullName = ( (Element) beanList.item(j)).getAttribute("class");
dealClassList.put(className,classFullName);
}
System.out.println("importJobList.size()" + importJobList.size());
System.out.println("dealClassList.size()" + dealClassList.size());
; insertNum = 1;
} else {
insertNum++;
}
}
} catch (Exception e) {
e.printStackTrace();
//---寫入數(shù)據(jù)庫(kù)待加入----
//log.error(e.getMessage());
}
}
public void close() {
if (conn != null) {
try {
if (conn != null) {
DbUtils.commitAndClose(conn);
System.out.println("close end");
}
} catch (SQLException e) {
e.printStackTrace();
//log.error(e.getCause());
}
}
}
/**
*
* @param dateString String
* @param format String
* @return Date
*/
public Date formatDate(String dateString,String format){
try{
SimpleDateFormat f = new SimpleDateFormat(format);
return f.parse(dateString);
}catch(Exception e){
return null;
}
}
}
八、調(diào)用示例
package fileimport;
import java.util.HashMap;
public class ImportFileExample {
public ImportFileExample() {
}
public static void main(String[] args) {
try {
String ls = "c:/temp/employee_test.csv";
以下內(nèi)容含腳本,或可能導(dǎo)致頁(yè)面不正常的代碼 |
---|
說(shuō)明:上面顯示的是代碼內(nèi)容。您可以先檢查過(guò)代碼沒(méi)問(wèn)題,或修改之后再運(yùn)行. |
以下內(nèi)容含腳本,或可能導(dǎo)致頁(yè)面不正常的代碼 |
---|
說(shuō)明:上面顯示的是代碼內(nèi)容。您可以先檢查過(guò)代碼沒(méi)問(wèn)題,或修改之后再運(yùn)行. |