女高中生上课自慰流白浆_金瓶梅全集在线观看_人妻互换免费中文字幕网站_国产玖玖资源站免费_最经典的人与动物故事

| 項目咨詢 |積分體系 | 加入收藏 | 設(shè)為首頁 | RSS
您當(dāng)前的位置:首頁 > 市場 > 百科 > 案例 > 技術(shù)應(yīng)用

重慶某醫(yī)院Oracle調(diào)整及升級報告

時間:2011-04-12 17:00:48  來源:  作者:
更多

 

基本情況及應(yīng)用規(guī)模
xxx第三人民醫(yī)院是一所集醫(yī)療、科研、教學(xué)為一體的綜合性三級甲等醫(yī)院。醫(yī)院現(xiàn)有病床650張,日門診量1000人次左右,住院人數(shù)500人左右。有26個臨床科室、11個醫(yī)技科室,并開設(shè)有60多個專科專病門診。
醫(yī)院目前使用了醫(yī)院信息系統(tǒng)標(biāo)準(zhǔn)版、門診醫(yī)生工作站系統(tǒng)、病案管理系統(tǒng)、LIS系統(tǒng)(LIS接口程序從ZLHIS中提取病人信息和并完成計費功能),沒有使用住院醫(yī)生工作站。高峰期用戶連接數(shù)160個左右,HIS系統(tǒng)工作站150臺左右。
醫(yī)院的軟硬件環(huán)境如下:

機器名
HISSERVER
用途
運行ZLHIS標(biāo)準(zhǔn)版及醫(yī)囑系統(tǒng)
硬件供貨商
IBM
型號
X365、X250雙機容錯環(huán)境
Cluster SoftWare
DataWare
操作系統(tǒng)
Windows 2000 Server(SP4)
內(nèi)存
4G DRR
CPU 個數(shù)
2
剩余磁盤空間(in %)
 
ORACLE實例數(shù)量
1
IP地址
192.168.0.3(雙機系統(tǒng)虛擬IP)
網(wǎng)絡(luò)環(huán)境
千兆骨干、百兆到桌面

 
問題現(xiàn)象
2006年3月8日,醫(yī)院系統(tǒng)管理人員報告,系統(tǒng)在業(yè)務(wù)高峰期的9:00:~11:00時段,門診收費時有停頓的現(xiàn)象,有時一張單據(jù)保存需要1分鐘左右的時間。LIS系統(tǒng)提取病人信息的速度非常慢,等待時間以分鐘計。由于整個系統(tǒng)的運行速度較慢,已影響到醫(yī)院正常業(yè)務(wù)的開展,醫(yī)院各科室的意見比較大。服務(wù)器CPU占用率近期從原來的15%增長到現(xiàn)在的40%左右。
與市二院的對比分析
市二院與市三院在業(yè)務(wù)規(guī)模和應(yīng)用規(guī)模上比較接近,我們希望從兩家醫(yī)院的應(yīng)用環(huán)境對比分析中找到一些解決問題的線索。
 

對比項目
市二院
市三院
服務(wù)器
HP DL680
2G內(nèi)存/2*Xeon CPU /SCSI 360 72.8G * 2
IBM X365 
4G內(nèi)存/2*Xeon CPU/SCSI 360 72.8G * 2
磁盤陣列
同有8210/ Raid 5 + Spare/128M Cache
寧波豪威/ Raid 5 + Spare/64M Cache
操作系統(tǒng)
Win 2000 Server(SP4)
Win 2000 Server(SP4)
數(shù)據(jù)庫系統(tǒng)
Oracle 10.1.3
Oracle 8.1.6
應(yīng)用系統(tǒng)
醫(yī)院信息系統(tǒng)標(biāo)準(zhǔn)版、住院醫(yī)生工作站
醫(yī)院信息系統(tǒng)標(biāo)準(zhǔn)版、門診醫(yī)生工作站、LIS系統(tǒng)(北京虹橋)
用戶連接數(shù)
140
160
站點數(shù)
140
150
數(shù)據(jù)大小
病人費用記錄1600萬行記錄
病人費用記錄1000萬行記錄
使用系統(tǒng)時間
4年
1.5年

 
從上表中,我們看到市二院啟用了住院醫(yī)生工作站系統(tǒng),沒有使用門診醫(yī)生工作站系統(tǒng),二家醫(yī)院在用戶連接數(shù)和硬件環(huán)境上都比較接近。市二院使用ZLHIS的時間要比市三院長,數(shù)據(jù)量也比市三院大,但市二院在使用過程中沒有反映速度慢的問題,系統(tǒng)運行速度比較理想。
通過以上的對比分析,我們發(fā)現(xiàn)以下的主要差異:
1、數(shù)據(jù)庫版本不同。市三院目前為816版本,市二院為10.1.3。
兩個版本的性能差異對ZLHIS而言,主要體現(xiàn)以下兩個方面:
   1)、10.1.3使用的本地管理的表空間(LMT),而816默認(rèn)情況下使用的是字典管理的表空間(DMT)。LMT很好的解決了DMT的遞歸SQL與熱塊爭用問題。可以帶來數(shù)據(jù)寫入和空間管理性能很大的提升。
   2)、10.1.3中本地管理的表空間,可以有效避免數(shù)據(jù)文件碎片,自動合并未使用的數(shù)據(jù)塊。
   3)、Oracle 10g新增的回退段自動管理功能,很好地解決了8i下的回退段設(shè)置問題,在8i下如果回退段設(shè)置不當(dāng),會嚴(yán)重地影響數(shù)據(jù)庫的性能。
2、cursor_sharing參數(shù)的不同
   進一步分析數(shù)據(jù)庫參數(shù),發(fā)現(xiàn)兩家醫(yī)院的cursor_sharing參數(shù)設(shè)置不相同。三院的設(shè)置為exact,也就是精確匹配。由于ZLHIS中綁定變量使用得不是很好,大量的SQL語句需要做硬分析(Hard Parse)。
   二院設(shè)置為similar,這是10g新增加的選項。簡單的講,為了解決僅僅因為列值不同而導(dǎo)致SQL語句不能共享的問題,引入了CURSOR_SHARING參數(shù),使這類SQL也可以使用共享SQL,從而提高效率,降低耗費在SQL語句解析上的CPU等各種資源。但使用similar選項也可以帶來一些問題,比如把空格也解析成綁定變量 ;市二院的一日費用清單的數(shù)據(jù)源就出現(xiàn)過這種問題。最好的方式還是在編程時就避免硬編碼的SQL語句,使用綁定變量。從二院的實際應(yīng)用效果,使用simimar選項,效果比較明顯。
3、市二院沒有使用LIS系統(tǒng)。
市三院的LIS系統(tǒng)與ZLHIS進行了連接,LIS系統(tǒng)接口從ZLHIS中讀取視圖(VIEW)提取病人信息,并調(diào)用ZLHIS數(shù)據(jù)庫的存儲過程(PROCEDURE)完成計費功能。
問題診斷
首先,我想到是否因為系統(tǒng)問題導(dǎo)致性能下降,所以到達現(xiàn)場后,依次進行了如下檢查:
1)、使用Windows 2000任務(wù)管理器查看CPU及內(nèi)存使用情況,CPU利用率偏高,且波動較大,符合系統(tǒng)管理員的描述,內(nèi)存利用率較為平穩(wěn)。
111.jpg
2)、使用Windows 2000的事件查看器查看操作系統(tǒng)日志,沒有發(fā)現(xiàn)異常。
3)、查看Oracle的后臺進程文件(alert_orcl.log),沒有發(fā)現(xiàn)異常。初步排除是Oracle錯誤引起的性能下降
4)、檢查磁盤陣列,沒有發(fā)現(xiàn)磁盤損壞,磁盤陣列工作正常。
5)、醫(yī)院管理人員配合檢查了網(wǎng)絡(luò)環(huán)境,確認(rèn)網(wǎng)絡(luò)設(shè)備工作正常,沒有出現(xiàn)不穩(wěn)定現(xiàn)象。
經(jīng)過以上的檢查分析,排除了硬件環(huán)境和操作系統(tǒng)方面的故障引起的性能下降,接下來,主要從應(yīng)用和數(shù)據(jù)庫方面進行分析與調(diào)整。
 
在診斷和調(diào)整過程中,主要使用Statspack和SQL_TRACE工具。
Oracle Statspack工具從816中開始引入Oracle中,已成為DBA用來診斷數(shù)據(jù)庫性能的強有力工具。它通過收集一組數(shù)據(jù)庫運行數(shù)據(jù),記錄數(shù)據(jù)庫的運行狀況,生成Statspack報告。通過對Statspack報告的分析確定性能的瓶頸所在。目前,Statspack工具已經(jīng)在Oracle性能調(diào)整中得到了廣泛應(yīng)用。
SQL_TRACE是Oracle提供的用于進行SQL跟蹤的手段。生成的Trace文件進行格式化后,提供了包括SQL文本,執(zhí)行計劃,執(zhí)行效率等重要信息;是強有力的輔助診斷工具.在日常的數(shù)據(jù)庫問題診斷和解決中,SQL_TRACE是非常常用的方法。
本次調(diào)整使用Statspack工具收集業(yè)務(wù)高峰期的系統(tǒng)運行情況,并以此作為調(diào)整的基礎(chǔ)。Sql_Trace主要用于跟蹤分析Statspack報告中的Top SQL部分的SQL語句,還用于定位引起個別功能運行速度較慢的SQL語句。
  經(jīng)過對Statspack報告的分析,我們初判斷影響性能的主要原因有:
1、“病人費用匯總”表的行級鎖定。醫(yī)保事務(wù)需要更新當(dāng)天的病人費用匯總表中的一行,獲得一個行級鎖定,當(dāng)普通業(yè)務(wù)也需要更新相同的行時,必須等待醫(yī)院業(yè)務(wù)事務(wù)完成,這種等待就造成了系統(tǒng)速度慢甚至是死機的現(xiàn)象。
2、從高峰期生成的Statspack報告中關(guān)于SQL共享使用的指標(biāo)都不理想,軟解析比率為:75.71%。原因是ZLHIS沒有很好的使用綁定變量,造成了語句大量的硬解析,耗費了大量的系統(tǒng)資源,這也是醫(yī)院CPU利用率增高的原因之一。
3、從報告的TOP SQL部分發(fā)現(xiàn)LIS接口提取病人信息的SQL邏輯讀很高,進一步使用SQL_Trace功能分析語句,發(fā)現(xiàn)這段SQL對“病人掛號記錄”和”病人信息”表都做了全表掃描,運行效率低下。
詳細的Statspack報告分析請參見附錄A和附錄B。
222.jpg
問題解決過程
   基于上述分析,于2006年3月12日將Oracle數(shù)據(jù)庫系統(tǒng)升級到了10.2.0,升級后主要做了以下調(diào)整:
1、使用cursor_sharing=similar參數(shù),以使ZLHIS的大量硬編碼的SQL語句能夠共享使用,解決綁定變量的問題,降低SQL硬解析的系統(tǒng)消耗。(關(guān)于使用綁定變量效率提升的實驗請參見附錄C)。
2、建立基于函數(shù)to_char的索引,改善LIS提取病人信息的SQL語句的執(zhí)行效率。
3、使用定時刷新的物化視圖代替“病人費用匯總”表,并創(chuàng)建一個“病人費用匯總”視圖,然后在視圖上建立替代觸發(fā)器,屏蔽掉程序的DML語句。
4、表空間全部采用ASSM方式的本地管理表空間(LMT),減少維護表空間的遞歸SQL消耗,避免Freelist的爭用。
經(jīng)過升級調(diào)整后,觀察CPU占用率從原來的平均45%左右,降到了現(xiàn)在的20%左右。
 
 
經(jīng)過升級調(diào)整后,LIS提取病人信息的速度有了明顯提高,檢驗科使用人員比較滿意,醫(yī)院各業(yè)務(wù)窗口部門普遍反映速度有了提高。
 
 
后續(xù)問題的處理
在Oracle8i下優(yōu)化器默認(rèn)為Choose方式(optimizer_mode=choose),Oracle 10g下優(yōu)化器默認(rèn)為All_rows(CBO的一種),為保證語句的執(zhí)行計劃與在8i下的一致性,并考慮到程序有的地方強行使用了RBO,將優(yōu)化器模式修改為choose。Oracle 10g對CBO有了更好的支持,但是由于優(yōu)化器和其他環(huán)境的變化導(dǎo)致了部分SQL語句在10g下運行速度較慢。 主要體現(xiàn)在以下兩個方面:
    1)、升級后部分藥品相關(guān)的模塊運行速度有了下降,對這部分SQL進行了調(diào)整,運行速度恢復(fù)正常。
2)、部分報表執(zhí)行速度較慢,接下來對系統(tǒng)中的報表SQL進行了集中優(yōu)化和調(diào)整。
調(diào)整SQL時主要使用了以下幾種方法:
1)、對相關(guān)表作分析(Analyze),收集準(zhǔn)確的統(tǒng)計信息。
2)、禁用部分不合理的索引,消除其對執(zhí)行計劃的影響,如:藥品收發(fā)記錄_IX_庫房ID。
3)、使用提示字(Hint),穩(wěn)定SQL語句的執(zhí)行計劃。
更為詳細SQL調(diào)整技巧請參見相關(guān)文檔。
 
總結(jié)
 此次數(shù)據(jù)庫分析調(diào)整印證了“60%的性能問題都是應(yīng)用問題”這句名言。使用cursor_sharing=similar只是權(quán)宜之際,并可能會帶來一定的副作用,我們的程序在綁定變量的使用上還有很長的路要走。“病人費用匯總”這種在當(dāng)初看起來不錯的設(shè)計,由于醫(yī)保業(yè)務(wù)的發(fā)展,在今天卻成為了一個嚴(yán)重影響性能的缺陷。我們在數(shù)據(jù)庫結(jié)構(gòu)設(shè)計中不能默守陳規(guī),必須適應(yīng)不斷變化的業(yè)務(wù)需要。
 有時,一條不良的SQL語句可能會導(dǎo)致整個系統(tǒng)的性能下降,影響客戶對整個系統(tǒng)的評價,最好的方式是在程序開發(fā)階段就把這些劣質(zhì)SQL扼殺在搖籃里,有時甚至為了性能,犧牲部分不實用的功能也是值得的,我們需要在性能與功能之間做出平衡。出現(xiàn)性能問題時我們需要用科學(xué)的方法分析解決問題,做出正確的判斷,而不是依據(jù)經(jīng)驗和主觀意識進行判斷。
 
 
附錄:
A、              調(diào)整前的Statspack報告分析
B、              調(diào)整后的Statspack報告對比分析
C、              升級過程及典型問題的處理
D、              LIS提取病人信息速度慢的解決過程
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
附錄A   調(diào)整前的Statspack報告分析
我們利用Oracle 的Statspack工具生成了上午10:15至11:00的報告,用以作為分析和調(diào)整的基礎(chǔ)。
1 數(shù)據(jù)庫壓力及緩沖區(qū)情況分析
Cache Sizes                                                                  
~~~~~~~~~~~                                                                  
           db_block_buffers:      128000                                      
              db_block_size:        8192                                     
                 log_buffer:     1048576                                     
           shared_pool_size:   314572800                                     
                                                                             
 
Load Profile                                                                 
~~~~~~~~~~~~                                                                 
                                       Per Second      Per Transaction       
                                  ---------------      ---------------       
                  Redo size:            16,906.18             8,828.71       
              Logical reads:            33,288.68            17,3894       
              Block changes:               121.76                658       
             Physical reads:                92.41                48.26       
            Physical writes:                10.52                 5.49       
                 User calls:               271.47               141.77       
                     Parses:                632                307       
                Hard parses:                15.38                 8.03       
                      Sorts:                26.16                166       
               Transactions:                 1.91                            
                                                                             
              Rows per Sort:    1,576.13                                     
 Pct Blocks changed / Read:        0.37                                     
         Recursive Call Pct:       48.71                                     
 Rollback / transaction Pct:        0.15       
 1)、Redo size:   16,906.18: 每秒鐘產(chǎn)生16,906.18字節(jié)的重做日志。每分鐘產(chǎn)生約1M左右的重做日志(16,906.18*60/1024),系統(tǒng)壓力相對還是比較大。
2)、Physical reads 92.41物理讀為92.41,很少基本可以忽略,初步判斷,高整緩沖的設(shè)置沒有太大的問題。
3)、Transactions: 1.91 每秒鐘2個事務(wù)左右,也證明系統(tǒng)壓力較大。
 
2實例效果分析
Instance Efficiency Percentages (Target 100%)                                
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                
        Buffer   Nowait Ratio:      100.00                                     
        Buffer   Hit   Ratio:       99.72                                      
        Library  Hit   Ratio:       921                                     
        Redo   NoWait Ratio:       99.99                                     
        In-memory Sort Ratio:       99.90                                      
        Soft Parse Ratio:       75.71                                     
        Latch Hit Ratio:       99.97  
1)、Buffer Hit   Ratio  99.72 從這部分看高速緩存命中率為99.72,比較理想,不需要再加大高速緩存。
2)、Soft Parse Ratio 75.71 。這項值低于90%,一般證明系統(tǒng)沒有很好的使用綁定變量。ZLHIS在綁定變量的使用上還有很長的路要走。建議升級到Oracle 9i/10g 使用cursor_sharing=similar參數(shù),可以取得較好的效果。
3)、In-memory Sort Ratio:       99.90,體現(xiàn)出排序基本上都在內(nèi)存中進行,不需要調(diào)整排序區(qū)。
 
3等待事件分析
Top 5 Wait Events                                                            
~~~~~~~~~~~~~~~~~                                                Wait      % Total
Event                                               Waits         Time (cs)    Wt Time
-------------------------------------------- ------------ ------------ -------
db file sequential read                                   235,854       138,851   87.46
enqueue                                                    45        9,025    5.68
SQL*Net more data from dblink                             3,300        4,448    2.80
SQL*Net message from dblink                                402        2,171    1.37
log file sequential read                                       810        1,062     .67
 
1) db file sequential read 為最主要的等待事件(87.46%),這通常是指單一的數(shù)據(jù)塊讀操作(例如,索引的讀。。該值過大說明表的連接順序很糟糕;蛘呤褂昧朔沁x擇性的索引。數(shù)據(jù)庫的主要調(diào)整方向為:優(yōu)化SQL,使用正確的索引,改善表連接效果。
2)enqueue閂鎖是底層的隊列機制,用于保護系統(tǒng)的全局區(qū)(SGA)的內(nèi)存結(jié)構(gòu)。使用本地管理的表空間(LMT)可以有效降低這部分等待事件,目前ZLHIS使用的是字典管理的表空間(DMT),會造成Fet$Uet$系統(tǒng)表的爭用(字典管理表空間使用這兩個表記錄字典管理表空間的使用情況,LMT使用了位圖(BITMAP)管理表空間,顯著地提高了效率。
3) SQL*Net more data from dblink、SQL*Net message from dblink,為系統(tǒng)空閑事件,可不必關(guān)注,造成這兩者較高的原因可能是ZLHIS通過網(wǎng)絡(luò)向醫(yī)保前置機大量取數(shù)產(chǎn)生的。
4)enqueue 進而查看報告的另一部分
Enqueue activity for DB: ORCL Instance: orcl Snaps:       2 - 3       
                                                                             
Enqueue            Gets      Waits                                            
---------- ------------ ----------                                           
TX                6,908          2                                              -------------------------------------------------------------       
發(fā)現(xiàn)主要為TX類型的Enqueue等待,一般而言通常有三種情況產(chǎn)生:
(1)、唯一索引中的重復(fù)索引,需要提交(commit)或回段(rollback)事務(wù)。
(2)、位圖索引的更新,由于ZLHIS中沒有使用位圖索引,所以這應(yīng)該不是主要原因。
(3)、多個用戶同時更新同一個塊,即熱點塊爭用。典型的就是“病人費用匯總”表的塊爭用問題,可以判定這是Enqueue等待事件較高的原因。
4磁盤IO分析
Tablespace IO Summary for DB: ORCL Instance: orcl Snaps:       2 -      3  
                                                                             
                                      Avg Read                  Total Avg Wait
Tablespace                      Reads   (ms)        Writes      Waits   (ms)  
------------------------- ----------- -------- ----------- ---------- --------
ZL9EXPENSE                    134,886      5.9       7,755         10      0.0
ZL9PATIENT                     88,595      5.6       1,196          0      0.0
SYSTEM                          5,781      6.9       4,053          0      0.0
ZL9MEDLST                       5,095      7.5       1,791          0      0.0
RBS                                38      9.7       2,837          9      0.0
TEMP                            1,809      0.0         967          0      0.0
ZL9CISREC                       1,584      6.8         484          0      0.0
ZL9BASEITEM                       787      9.7         209          2      0.0
ZLTOOLSTBS                        656      8.3           5          0      0.0
USERS                              10      2.0         259          0      0.0
ZLTOOLSTMP                         23      0.0          87          0      0.0
ZL9DUEREC                          30      4.0           5          0      0.0
ZL9HISTORY                          7      1.4           5          0      0.0
DRSYS                               5      0.0           5          0      0.0
INDX                                5      0.0           5          0      0.0
TOOLS                               5      0.0           5          0      0.0
         -------------------------------------------------------------    
從statspack報告的磁盤IO部分來看,發(fā)現(xiàn)ZLEXPENSE和ZLPATIENT的磁盤IO最大。ZLEXPENSE上面存儲了費用相關(guān)的表,IO大是正常的。ZL9PATIENT的IO偏大是不正常的,可以判定是由于LIS系統(tǒng)提取病人信息的的全表掃描引起大量的磁盤IO。可以看到,解決LIS系統(tǒng)提取病人信息的全表掃描,是系統(tǒng)調(diào)整的一個關(guān)鍵點。
5低效SQL分析
 
SQL ordered by Gets for DB: ORCL Instance: orcl Snaps:       2 -      3    
                                                                             
                                Gets       % of                              
   Buffer Gets     Executes   per Exec    Total   Hash Value                 
-------------- ------------ ------------ ------ ------------                 
SQL statement                                                                 
------------------------------------------------------------------------------
    16,933,155        4,275      3,961.0   18.8   2331755529                 
UPDATE 病人費用匯總 SET 結(jié)帳金額=NVL(結(jié)帳金額,0) + :b1 WHERE 日期 = TRUNC(SYS
                                                                             
    11,084,772          623     17,792.6   12.3   2504304975                 
SELECT NVL(SUM(實收金額),0)   FROM 病人費用記錄 WHERE 病人ID + 0 = :b1 AND
                                                                             
     3,738,223          102     36,649.2    4.2    467005032                 
 Select B.登記時間,A.病人ID,A.門診號,B.NO,Nvl(A.姓名,' ') as 姓名, A.性別,A.
                                                                              
     3,198,259          803      3,982.9    6   4234930587                 
UPDATE 病人費用匯總 SET 應(yīng)收金額=NVL(應(yīng)收金額,0) + :b1 ,實收金額=NVL(實收金額,
                                                                              
     1,966,927          510      3,856.7    2.2   4224504530                 
UPDATE 病人費用匯總 SET 應(yīng)收金額=NVL(應(yīng)收金額,0) + :b1 ,實收金額=NVL(實收金額,
                                                                             
     1,557,260          328      4,747.7    1.7   1195480746                 
Select Distinct    P.ID,P.號碼 as 號別,P.號類,P.科室ID,B.名稱 As 科室,P.項目ID
                                                                             
     1,311,536          336      3,904    1.5      7273237                 
UPDATE 病人費用匯總 SET 應(yīng)收金額=NVL(應(yīng)收金額,0) + :b1 ,實收金額=NVL(實收金額,
                                                                             
     1,304,408           92     14,178.3    1.4   1249658810                 
Select Rownum as KeyID,A.* From ( Select A.類別 AS 類別ID,E.ID as 診療項目ID,
                                                                             
     1,262,369          202      6,249.4    1.4   3289008884                 
Select A.*,Nvl(B.使用時間,To_Date('1900-01-01','YYYY-MM-DD')) As 使用時間 From
                                                                             
     1,080,637          177      6,105.3    1.2    137210266                 
Select A.*,Nvl(B.使用時間,To_Date('1900-01-01','YYYY-MM-DD')) As 使用時間 From
 
從SQL ordered by Gets部分可以看出,大部分的低效SQL大多數(shù)都與“病人費用匯總”有關(guān),而且多以update操作為主。在ZLHIS中很多存儲過程都要update“病人費用匯總”表,且很多update語句沒有很好用到索引。還有就是update語句需要獲得Oracle行級排它鎖,這也是造成Enqueue等待事件較高的原因。解決”病人費用匯總”行級鎖定和訪問效率是提高運行速度的又一關(guān)鍵點。
6連接用戶數(shù)分析
 在32位平臺上,Oracle進程的內(nèi)存尋址空間有2G的限制,實際上Oracle.exe進程能夠使用的內(nèi)存為1.75G左右。那么SGA+PGA只能有1.75G左右。市三院在高峰期會話數(shù)有180左右,最大時達到230個session。由于使用專用服務(wù)器,每個Session大概需要2M左右的合內(nèi)存。所以整個 SGA不能大于1290M (1750M-460M)。
 在實例SGA設(shè)置時,正是遵循了上述的原則。要使用更大的SGA,有兩種解決方案:
 1)、使用共享服務(wù)器模式。但由于ZLHIS系統(tǒng)有很多的大事務(wù)要運行,這種模式會帶來,會話事務(wù)處理的等待。
 2)、將平臺升級到64bit。這需要大量的硬件和軟件投資。
 由于從Statspack的分析來看,SGA各個部分的使用效果都不錯,所以沒有調(diào)整SGA的必要。
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
附錄B 調(diào)整后的Statspack報告對比分析
升級后Oracle10g并進行調(diào)整后,我們在同一時間段生成Staspack報告,發(fā)現(xiàn)各項指標(biāo)有了明顯改善。報告的前半部分如下:
STATSPACK report for
 
Database                            DB Id
Instance                         Inst Num
Startup Time                     Release
RAC
~~~~~~~~                         -----------------------                     --------                                  1112179643 orcl                1
07-3 -06 07:3 10.2.0.1.0 NO
4
Host Name:   HISSERVER        Num CPUs:    4
Phys Memory (MB):    3,583
~~~~
Snapshot       Snap Id     Snap Time      Sessions Curs/Sess Comment
~~~~~~~~    ---------- ------------------ -------- --------- -------------------
Begin Snap:          1 08-3 -06 10:14:16     161      28.2
 End Snap:         11 08-3 -06 10:58:44     156      30.6
   Elapsed:               44.47 (mins)
 
Cache Sizes                       Begin        End
~~~~~~~~~~~                  ---------- ----------
               Buffer Cache:       800M             Std Block Size:         8K
           Shared Pool Size:       200M
     Log Buffer:                     6,860K
 
Load Profile                            Per Second       Per Transaction
~~~~~~~~~~~~                       ---------------       ---------------
                  Redo size:             12,685.88              6,535.22
              Logical reads:             11,708.79              6,031.87
              Block changes:                 81.76                 42.12
             Physical reads:                 56.86                 29.29
            Physical writes:                  6.28                  24
                 User calls:                278.34                1439
                     Parses:                100.27                 51.65
                Hard parses:                 12.57                  6.47
                      Sorts:                 39.76                 20.49
                     Logons:                  0.12                  0.06
                  Executes:                141.92                 711
               Transactions:                  1.94
 
 % Blocks changed per Read:    0.70    Recursive Call %:                76.19
 Rollback per transaction %:    0.14       Rows per Sort:               309.51
 
Instance Efficiency Percentages
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            Buffer Nowait %:   99.96       Redo NoWait %: 100.00
            Buffer Hit   %:   99.51    In-memory Sort %: 100.00
            Library Hit   %:   94.87        Soft Parse %:   87.47
         Execute to Parse %:   29.35         Latch Hit %:   99.93
Parse CPU to Parse Elapsd %:   87.81     % Non-Parse CPU:   91.11
 
 Shared Pool Statistics        Begin   End
                               ------ ------
             Memory Usage %:   894   80.73
    % SQL with executions>1:   796   75.00
 % Memory for SQL w/exec>1:   87.20   89.54
 
Top 5 Timed Events                                                    Avg %Total
~~~~~~~~~~~~~~~~~~                                                   wait   Call
Event                                            Waits    Time (s)   (ms)   Time
----------------------------------------- ------------ ----------- ------ ------
CPU time                                                     2,754          71.8
db file sequential read                         92,563         718      8   18.7
read by other session                           12,429         156     13    4.1
db file scattered read                           8,398         127     15    3
latch: shared pool                               1,652          27     16     .7
          -------------------------------------------------------------
相比8i下的statspack主要有以下幾點改善:
1)、Soft Parse %:   87.47
Sql語句軟解析比率有了很大的提高,提高了10%左右,主要是在10g使用了cursor_sharing=similar參數(shù)。
2)、Enqueue等待事件不再是主要的等待事件,主要是得益于將“病人費用匯總”用物化視圖代替,減少了表的行級鎖定。
3)、最主要的等待事件變成了CPU time,此事件為Oracle空閑事件,空閑事件是不能避免的,在性能調(diào)整中,不必太關(guān)注此類事件。
4)、TOP 5 部分的幾個等待事件等待時間都很小。對比8i下的top5中的幾個等待事件的等待時間減少了很多。 如db file sequential read 由原來的138,851ms,減少到現(xiàn)在的718ms?梢姼纳频姆冗是很大的。
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
附錄C 升級過程及典型問題的處理
1、時間安排
 

時間
事項
說明
12:00
安裝介質(zhì)準(zhǔn)備
Oracle 10.2.0 RDBMS光盤
12:30
模擬升級
利用上周的冷備份進行模擬升級
15:00
解決模擬升級中的問題,測試
作好相關(guān)解決記錄
20:00
開始正式升級
通知相關(guān)科室,系統(tǒng)停止使用
20:10
配置Dataware雙機環(huán)境
清除DataWare雙機中資源中的Oracle服務(wù)
20:20
備份數(shù)據(jù)庫
冷備份數(shù)據(jù)庫并作EXP邏輯備份(均要求異地存檔)
21:00
冷備份數(shù)據(jù)驗證
異地進行
21:10
卸載Oracle 816
 
21:30
安裝Oracle 10.2.0
包括建立新數(shù)據(jù)庫實例
22:00
對新實例進行配置
主要是配置初始化參數(shù)和歸檔日志路徑
22:30
導(dǎo)入數(shù)據(jù)
使用先前的邏輯備份的DMP文件
00:30
數(shù)據(jù)驗證
 
00:50
數(shù)據(jù)庫連接用戶數(shù)測試
使用編寫的VB程序
01:10
重新配置DataWare環(huán)境
 
01:40
雙機環(huán)境及用戶測試
 
01:50
冷備份升級成功的數(shù)據(jù)庫
 
02:00
升級完成
 

 
2、升級過程難點問題的解決
1)、表空間的處理。
由于10G與8I的數(shù)據(jù)文件默認(rèn)存放路徑不一致,不能直接導(dǎo)入表空間,需要先創(chuàng)建相關(guān)的表空間。我在8i下用SQL生成SQL的方式重新創(chuàng)建表空間的腳本,對生成的后稍加修改,就是創(chuàng)建表空間的腳本。
SQL> select 'create tablespace '||a.name||' datafile '''||b.name
 2         ||''' size 100m autoextend on EXTENT MANAGEMENT LOCAL AUTOALLOCATE   BLOCKSIZE 8K ;' as cmd
 3 from v$tablespace A,v$datafile b
 4 where a.TS#=b.TS#
 5 ;
 CMD
 ……………………………………………………………………………………
create tablespace SS datafile 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SS01.DBF' size 100m autoextend on EXTENT MANAGEMENT LOCAL AUTOALLOCATE   BLOCKSIZE 8K ;
……………………………….
28 rows selected
 
SQL>
2)、IMP – 00020錯誤的解決。
在導(dǎo)入“病人信息”表時出現(xiàn)IMP-00020錯誤。
 導(dǎo)入了                                                             0
. . 正在導(dǎo)入表                  "病人未結(jié)費用"
導(dǎo)入了                                                         10793
. . 正在導(dǎo)入表                      "病人信息"
IMP-00020: 列緩沖區(qū)大小 (4) 的長列過大
. . 正在導(dǎo)入表                  "病人醫(yī)囑發(fā)送"
導(dǎo)入了                                                        263066
 
   病人信息不能導(dǎo)入,查詢Oracle MetaLink此錯誤的解釋為:
由于在”病人信息”上使用了基于to_char的函數(shù)索引,先懷疑是函數(shù)的問題。按照metaLink的解釋,先試著加大導(dǎo)入時的buffer和使用commit=y、constrains=n、indexes=n參數(shù),還是出現(xiàn)同樣的錯誤。于是初步判斷是由于導(dǎo)出時,使用了direct=y造成的,是遇上了816的一個bug。于是決定使用冷備份還原,重新導(dǎo)出“病人信息”表, 重新導(dǎo)入成功,至此問題解決。
3、Oracle 10g的參數(shù)設(shè)置
Parameter Name                Begin value                       (if different)
----------------------------- --------------------------------- --------------------------------------------------------------------------------
audit_file_dest                   D:\ORACLE\PRODUCT\10.2.0\ADMIN\OR
background_dump_dest          D:\ORACLE\PRODUCT\10.2.0\ADMIN\OR
compatible                      10.2.0.1.0
control_files                     F:\ORACLE\ORADATA\ORCL\CONTROL01.
core_dump_dest                 D:\ORACLE\PRODUCT\10.2.0\ADMIN\OR
cursor_sharing                  SIMILAR
db_block_size                   8192
db_cache_size                  838860800
db_domain                     DOMAIN
db_file_multiblock_read_count 16
db_name                       ORCL
db_recovery_file_dest            d:\oracle\product\10.2.0/flash_re
db_recovery_file_dest_size       2147483648000
dispatchers                     (PROTOCOL=TCP) (SERVICE=ORCLXDB)
java_pool_size                  25165824
job_queue_processes           10
large_pool_size                 16777216
log_archive_dest_1              LOCATION=D:\oracle\product\10.2.0
log_archive_dest_2              LOCATION=F:\oracle\ORADATA\ORCL\A
log_archive_format              ARC%S_%R.%T
open_cursors                   300
optimizer_mode                 CHOOSE
pga_aggregate_target           1073741824
processes                      400
remote_login_passwordfile        EXCLUSIVE
sga_max_size                  1325400064
shared_pool_size               209715200
spfile                           D:\ORACLE\PRODUCT\10.2.0\DB_1\DBS
undo_management              AUTO
undo_tablespace                UNDOTBS1
user_dump_dest                 D:\ORACLE\PRODUCT\10.2.0\ADMIN\OR
------------------------------------------------------------------------------------------------------------------------------------------------
主要參數(shù)說明:
1)、SGA使用手動管理。從實際市二院等醫(yī)院的使用情況來看,自動管理SGA的效果不是很好,可能跟ZLHIS的應(yīng)用有關(guān)。各SGA的大小參照8i下的SGA設(shè)置,因為從前面的分析來看,8i下的SGA沒有什么大的問題,運行效果較好。
 
2)、Cursor_sharing = similar參數(shù)的使用,使用此參數(shù)的目的在于SQL語句軟件解析的比率。此參數(shù),可以讓一些硬編碼的SQL語句,使用綁定變量,這由Oracle自動完成,下面是Trace出來一段業(yè)務(wù)SQL。
Select Distinct A.ID,A.編碼,A.名稱
From
 部門表 A,部門性質(zhì)說明 B Where A.ID=B.部門ID And (B.服務(wù)對象 in(:"SYS_B_0",
 :"SYS_B_1",:"SYS_B_2")) And B.工作性質(zhì) IN (:"SYS_B_3") And (A.撤檔時間 is
 NULL or Trunc(A.撤檔時間)=To_Date(:"SYS_B_4",:"SYS_B_5")) Order by A.編碼
   可以看到Oracle已經(jīng)對SQL語句使用了綁定變量,也就節(jié)約了解析時間,但這個參數(shù)可能會帶來一些副作用,比如把空格翻譯成綁定變量等,但從目前使用的情況來看,可以帶來一定的性能提升。最根本解決綁定變量問題的途徑只有一個:修改軟件,使用綁定變量。
   下面通過一個實驗來看使用與不使用綁定變量之間的性能差別:
 
 
 
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as zlhis
 
SQL>
SQL> --創(chuàng)建兩個結(jié)構(gòu)完全一樣的表
SQL> create table test_bindvar (x number) ;
 
Table created
 
SQL> create table test_unbindvar (x number) ;
 
Table created
 
SQL> --使用綁定變量,使用動態(tài)SQLusing選項
SQL> declare
 2 v_sql varchar2(400);
 3 begin
 4   dbms_output.put_line('開始時間:'||to_char(sysdate,'hh24:mi:ss'));
 5   for i in 1..100000 loop
 6    execute immediate 'insert into test_bindvar values(:x)' using i ;
 7   end loop;
 8   dbms_output.put_line('結(jié)束時間:'||to_char(sysdate,'hh24:mi:ss'));
 9 end;
 10 /
 
開始時間:16:17:33
結(jié)束時間:16:17:38
 
PL/SQL procedure successfully completed
 
SQL> --不使用綁定變量,直接”sql
SQL> declare
 2 v_sql varchar2(400);
 3 begin
 4   dbms_output.put_line('開始時間:'||to_char(sysdate,'hh24:mi:ss'));
 5   for i in 1..100000 loop
 6    execute immediate 'insert into test_unbindvar values('||to_char(i)||')';
 7   end loop;
 8   dbms_output.put_line('結(jié)束時間:'||to_char(sysdate,'hh24:mi:ss'));
 9 end;
 10 
 11 /
 
開始時間:16:17:38
結(jié)束時間:16:19:08
 
PL/SQL procedure successfully completed
 
SQL> select count(*) from test_bindvar;
 
 COUNT(*)
----------
    100000
 
SQL> select count(*) from test_unbindvar;
 
 COUNT(*)
----------
    100000
 
SQL>
 
 我們看到同樣插入100000行數(shù)據(jù),使用綁定變量用了5秒鐘時間,而不使用綁定變量,共用了1分30秒鐘。兩者的性能差別居然有18倍的差距!可以說目前ZLHS最大的性能問題,主要是沒有使用綁定變量。
3)、processes,默認(rèn)為150,太小,加大到400。
4、連接用戶數(shù)的測試
   用VB寫了個小程序,使用ADO循環(huán)連接Oracle,測試可以連接的最大用戶數(shù)。發(fā)現(xiàn)只有200個SESSION左右。雖然醫(yī)院的高峰期的會話數(shù)只有180左右,但為了保證有擴展性,決定調(diào)整Oracle.exe進程的堆棧大小。注意必須停止Oracle服務(wù)才能調(diào)整,且當(dāng)前目錄必須為Oracle.exe的當(dāng)前目錄。
D:\oracle\product\10.2.0\db_1\BIN>orastack oracle.exe 500000
 
Dump of file oracle.exe
 
Current Reserved Memory per Thread = 1048576
Current Committed Memory per Thread = 4096
 
New Reserved Memory per Thread = 500000
 
D:\oracle\product\10.2.0\db_1\BIN>
   調(diào)整后的連接數(shù)可以達到250左右。
 
 
 
5、對表及索引進行分析(ANALYZE)
是由于升級到10g后,默認(rèn)使用CBO優(yōu)化器,而CBO必須依賴準(zhǔn)確的統(tǒng)計信息來確定SQL語句的執(zhí)行計劃。統(tǒng)計信息錯誤,將會影響SQL語句的執(zhí)行計劃,使Oracle使用錯誤的執(zhí)行路徑,從而影響執(zhí)行速度。使用ANALYZE命令對表進行分析:
用SQL生成SQL的方式產(chǎn)生分析腳本對表進行全表分析。
         select 'analyze table '||table_name||
       '  computed statistics for all indexes for all indexed columns ;'
       from dba_tables where owner='ZLHIS'
       and table_name not in ('病人費用記錄','藥品收發(fā)記錄')
病人費用記錄和藥品收發(fā)記錄由于數(shù)據(jù)量太大,對其只進行5%的采樣分析。
analyze table 病人費用記錄 estimate statistics sample 5 percent for all indexed columns for all  indexes
analyze table 藥品收發(fā)記錄 estimate statistics sample 5 percent for all indexed columns for all  indexes
6、<匯總打印發(fā)藥清單>速度很慢
通過分析報表數(shù)據(jù)源,發(fā)現(xiàn)<發(fā)藥時間>參數(shù)SQL對藥品收發(fā)記錄使用了全表掃描。
SQL語句:
select distinct A.審核日期,名稱
from 藥品收發(fā)記錄 A,部門表 B
where A.審核日期 between sysdate-30 and sysdate and A.對方部門id=B.id
and A.單據(jù) In (10) and A.發(fā)藥方式=3 And Mod(A.記錄狀態(tài),3)=1
order by A.審核日期 desc  
是由于升級到10g后,使用了CBO優(yōu)化器,而藥品收發(fā)記錄的統(tǒng)計信息還沒有更新,導(dǎo)致Oracle使用了全表掃描,而不是使用審核日期上的建立的索引。前面做5%的采樣分析獲得的統(tǒng)計信息不準(zhǔn)確。決定對藥品收發(fā)記錄表進行全表分析。
analyze table 藥品收發(fā)記錄compute statistics for all indexed columns for indexes
 
 
 
7、進入<病人一日費用清單>功能模塊速度很慢
  使用SQL_TRACE功能產(chǎn)生Trace文件。分析產(chǎn)生的Trace文件發(fā)現(xiàn)如下一段:
**************************************************************************************************************************
Select L.病人id,L.主頁id,I.姓名,I.住院號,LPAD(P.出院病床,:"SYS_B_0",
 :"SYS_B_1") as 床號, I.性別,P.入院日期,P.出院日期,P.險類,P.病人性質(zhì),P.費別,
 X.名稱 as 病區(qū)
From
 部門表 X,病人信息 I,病案主頁 P,(Select Distinct 病人id,主頁id From
 病人費用記錄 Where 登記時間 Between to_Date(:"SYS_B_2",:"SYS_B_3") and
 to_date(:"SYS_B_4",:"SYS_B_5") And 記錄狀態(tài) IN(:"SYS_B_6",:"SYS_B_7",
 :"SYS_B_8") ) L Where I.病人id=P.病人id and P.病人id=L.病人id and P.主頁id=
 L.主頁id And P.當(dāng)前病區(qū)ID=X.ID And P.出院日期 is NULL And P.險類 is NULL
 Order BY 病區(qū),床號
 
call     count       cpu    elapsed       disk      query    current        rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse        2      0.01       0.01          0          0          0           0
Execute      2      0.00       0.00          0          0          0           0
Fetch       35      1.96     106.43      16541      87107          0         307
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total       39      1.98     106.44      16541      87107          0         307
 
Misses in library cache during parse: 2
Optimizer mode: CHOOSE
Parsing user id: 690 
Rows     Row Source Operation
------- ---------------------------------------------------
    146 SORT ORDER BY (cr=42727 pr=16384 pw=0 time=104493303 us)
    146   VIEW (cr=42727 pr=16384 pw=0 time=104493063 us)
    146    HASH UNIQUE (cr=42727 pr=16384 pw=0 time=104492765 us)
   3011     FILTER (cr=42727 pr=16384 pw=0 time=8365121 us)
   3011      NESTED LOOPS (cr=42727 pr=16384 pw=0 time=8356030 us)
   3011       HASH JOIN (cr=33692 pr=16380 pw=0 time=8274701 us)
    207        TABLE ACCESS FULL 部門表 (cr=7 pr=0 pw=0 time=521 us)
   3011        TABLE ACCESS BY INDEX ROWID 病人費用記錄 (cr=33685 pr=16380 pw=0 time=8238586 us)
 122201         NESTED LOOPS (cr=1312 pr=446 pw=0 time=4889863 us)
    177          TABLE ACCESS FULL 病案主頁 (cr=631 pr=0 pw=0 time=27425 us)
 122023          INDEX RANGE SCAN 病人費用記錄_IX_病人ID (cr=681 pr=446 pw=0 time=1742897 us)(object id 52063)
   3011       TABLE ACCESS BY INDEX ROWID 病人信息 (cr=9035 pr=4 pw=0 time=122297 us)
   3011        INDEX UNIQUE SCAN 病人信息_PK (cr=6024 pr=4 pw=0 time=89468 us)(object id 52143)
發(fā)現(xiàn)這段提取病人信息的SQL使用“病人費用記錄”表來實現(xiàn)只顯示產(chǎn)生費用的病人信息。這段SQL的物理讀非常大(16541,紅色字體部分) 進一步分析下面的執(zhí)行計劃發(fā)現(xiàn),使用的”病人費用記錄_IX_病人ID索引,由于當(dāng)前在院的病人數(shù)較多,效率很低。一日清單一般只需要查詢當(dāng)天的費用,應(yīng)該“登記時間”索引的效率。問題原因與7.1一樣,都是對象的統(tǒng)計信息不準(zhǔn)確造成的。解決辦法同樣是對表作全表分析。
analyze table 病人費用記錄compute statistics for all indexed columns for indexes
 
8、升級檢查、用戶測試
使用服務(wù)器管理工具對導(dǎo)入的數(shù)據(jù)進行檢查、修正。以非ZLHIS用戶進行各種業(yè)務(wù)的測試。至此升級完成。
 
附錄D LIS提取病人信息速度慢的解決過程
1、問題現(xiàn)象
檢驗科LIS系統(tǒng)通過接口程序提取zlhis病人信息速度很慢,以分鐘計算。
2、故障分析
可能是提取病人信息的VIEW的SQL的執(zhí)行效率低下,根據(jù)執(zhí)行計劃調(diào)整SQL語句。
3、解決過程
查看原始的視圖語句:
create or replace view patientinfo as
Select
                   to_char(A.門診號) as 門診號,to_char(A.住院號) as 住院號,A.姓名,
    Decode(A.性別,'','M','','F','U') AS 性別,
                   A.年齡,'Y' AS 年齡單位,'0'||C.編碼 AS 科室號,C.名稱 AS 科室,
                   to_char(B.出院病床) AS 床號,D.編號 AS 醫(yī)生號,E.描述信息 AS 入院診斷,
                   '非基本醫(yī)保' AS 付款類型,decode(a.當(dāng)前科室id,null,'O','I') AS 病人類別
         From 病人信息 A,病案主頁 B,部門表 C,人員表 D,診斷情況 E
         Where A.病人ID=B.病人ID(+) And A.住院次數(shù)=B.主頁ID(+)
                   And B.出院科室ID=C.ID(+) And B.住院醫(yī)師=D.姓名(+)
                   And B.病人ID=E.病人ID(+) And B.主頁ID=E.主頁ID(+) And
     E.診斷類型(+)=1 and a.當(dāng)前科室id is not null
union
Select
                   to_char(A.門診號) as 門診號,to_char(A.住院號) as 住院號,A.姓名,Decode(A.性別,'','M','','F','U') AS 性別,
                   A.年齡,'Y' AS 年齡單位,'0'||j.科室號 AS 科室號,C.名稱 AS 科室
                   ,to_char(B.出院病床) AS 床號,D.編號 AS 醫(yī)生號,E.描述信息 AS 入院診斷,
                   '非基本醫(yī)保' AS 付款類型,decode(a.當(dāng)前科室id,null,'O','I') AS 病人類別
         From 病人信息 A,病案主頁 B,部門表 C,人員表 D,診斷情況 E,
 (select distinct (select 編碼 from 部門表 where id=執(zhí)行部門id) as 科室號,門診號 from 病人掛號記錄 ) j
         Where A.病人ID=B.病人ID(+) And A.住院次數(shù)=B.主頁ID(+)
                   And B.出院科室ID=C.ID(+) And B.住院醫(yī)師=D.姓名(+) and a.門診號=j.門診號(+)
                   And B.病人ID=E.病人ID(+) And B.主頁ID=E.主頁ID(+) And E.診斷類型(+)=1 and a.當(dāng)前科室id is null
 
提取LIS接口程序讀取病人信息的SQL語句,查看語句的執(zhí)行計劃:
SQL語句:select * from patientinfo where 住院號 ='154426' 的執(zhí)行計劃如下:
Explain plan:
SELECT STATEMENT, GOAL = CHOOSE                                              
VIEW     Object owner=ZLHIS        Object name=PATIENTINFO                       
 SORT UNIQUE        
 TABLE ACCESS FULL Object owner=ZLHIS         Object name=病人信息                       
………………..
 TABLE ACCESS FULL Object owner=ZLHIS         Object name=病人信息                       
      ………………
     SORT JOIN                                           
      VIEW      Object owner=ZLHIS                                    
      SORT UNIQUE                                            
      TABLE ACCESS FULL   Object owner=ZLHIS         Object name=病人掛號記錄               
分析語句的執(zhí)行計劃,發(fā)現(xiàn)病人信息、病人掛號記錄表等為全表掃描。首先需要消除對“病人掛號記錄“的全表掃描。
SQL> select count(*) from 病人掛號記錄;
 
 COUNT(*)
----------
    478299
發(fā)現(xiàn)病人掛號記錄有478299條記錄,數(shù)據(jù)量還是比較大。進一步分析語句,發(fā)現(xiàn)條件中有A.門診號=J.門診號,其中A表為病人信息,J表為病人掛號記錄。查看兩個表的索引情況。
SQL> select b.table_name,b.index_name,a.column_name
 2 from dba_ind_columns A,dba_indexes b
 3 where a.index_owner=b.owner
 4 and   a.index_name=b.index_name
 5 and   b.owner='ZLHIS'
 6 and   b.table_name in ('病人掛號記錄','病人信息')
 7 ;
 
TABLE_NAME                     INDEX_NAME                     COLUMN_NAME
------------------------------ ------------------------------ --------------------------------------------------------------------------------
病人掛號記錄                   病人掛號記錄_IX_病人ID         病人ID
病人掛號記錄                   病人掛號記錄_IX_操作員姓名     操作員姓名
病人掛號記錄                   病人掛號記錄_IX_登記時間       登記時間
病人掛號記錄                   病人掛號記錄_IX_執(zhí)行部門ID     執(zhí)行部門ID
病人掛號記錄                   病人掛號記錄_IX_執(zhí)行時間       執(zhí)行時間
病人掛號記錄                   病人掛號記錄_IX_執(zhí)行狀態(tài)       執(zhí)行狀態(tài)
病人掛號記錄                   病人掛號記錄_PK                ID
…………………………………………..
病人信息                       病人信息_PK                    病人ID
病人信息                       病人信息_UQ_就診卡號           就診卡號
18 rows selected
SQL>
   發(fā)現(xiàn)病人掛號記錄的門診號上都沒有建立索引,在表的“門診號”字段上建立索引。
SQL> create index 病人掛號記錄_IX_門診號 on 病人掛號記錄 (門診號)
      tablespace ZL9PATIENT;
      index created
SQL>
   改造原來的(select distinct (select 編碼 from 部門表 where id=執(zhí)行部門id) as 科室號,門診號 from 病人掛號記錄 )語句,將子查詢的方式改為直接表連接。
改造后的SQL語句如下:
create or replace view patientinfo as
Select      to_char(A.門診號) as 門診號,to_char(A.住院號) as 住院號,A.姓名,
    Decode(A.性別,'','M','','F','U') AS 性別,
                   A.年齡,'Y' AS 年齡單位,'0'||C.編碼 AS 科室號,C.名稱 AS 科室,
                   to_char(B.出院病床) AS 床號,D.編號 AS 醫(yī)生號,E.描述信息 AS 入院診斷,
                   '非基本醫(yī)保' AS 付款類型,decode(a.當(dāng)前科室id,null,'O','I') AS 病人類別
         From 病人信息 A,病案主頁 B,部門表 C,人員表 D,診斷情況 E
         Where A.病人ID=B.病人ID(+) And A.住院次數(shù)=B.主頁ID(+)
                   And B.出院科室ID=C.ID(+) And B.住院醫(yī)師=D.姓名(+)
                   And B.病人ID=E.病人ID(+) And B.主頁ID=E.主頁ID(+) And
     E.診斷類型(+)=1 and a.當(dāng)前科室id is not null
union
Select distinct
                   to_char(A.門診號) as 門診號,to_char(A.住院號) as 住院號,A.姓名,Decode(A.性別,'','M','','F','U') AS 性別,
                   A.年齡,'Y' AS 年齡單位,'0'||s.編碼 AS 科室號,C.名稱 AS 科室
                   ,to_char(B.出院病床) AS 床號,D.編號 AS 醫(yī)生號,E.描述信息 AS 入院診斷,
                   '非基本醫(yī)保' AS 付款類型,decode(a.當(dāng)前科室id,null,'O','I') AS 病人類別
         From 病人信息 A,病案主頁 B,部門表 C,人員表 D,診斷情況 E,
 病人掛號記錄 J,部門表 S
         Where a.門診號=J.門診號(+)
    and j.執(zhí)行部門id=s.id (+)
    and A.病人ID=B.病人ID(+) And A.住院次數(shù)=B.主頁ID(+)
                   And B.出院科室ID=C.ID(+) And B.住院醫(yī)師=D.姓名(+) and a.門診號=j.門診號(+)
                   And B.病人ID=E.病人ID(+) And B.主頁ID=E.主頁ID(+) And E.診斷類型(+)=1 and a.當(dāng)前科室id is null
改造后的SQL語句性能有了很大的很高,提取一個病人的信息由原來的30秒鐘左右,提高到現(xiàn)在的5秒鐘左右。再次查看執(zhí)行計劃:
SELECT STATEMENT, GOAL = CHOOSE                                             
 VIEW       Object owner=ZLHIS         Object name=PATIENTINFO                       
 SORT UNIQUE                                          
   UNION-ALL                                              
          ……………….
         TABLE ACCESS FULL       Object owner=ZLHIS         Object name=病人信息                       
          ……………….
          TABLE ACCESS FULL     Object owner=ZLHIS         Object name=病人信息                       
          TABLE ACCESS BY INDEX ROWID Object owner=ZLHIS         Object name=病案主頁                       
           INDEX UNIQUE SCAN Object owner=ZLHIS         Object name=病案主頁_PK                        
         ……………………     
        TABLE ACCESS BY INDEX ROWID     Object owner=ZLHIS         Object name=部門表                           
         INDEX UNIQUE SCAN      Object owner=ZLHIS         Object name=部門表_PK                   
       TABLE ACCESS BY INDEX ROWID       Object owner=ZLHIS         Object name=病人掛號記錄                        
        INDEX RANGE SCAN          Object owner=ZLHIS         Object name=病人掛號記錄_IX_門診號                      
                 
   發(fā)現(xiàn)病人費用記錄已經(jīng)使用索引,但病人信息表還是全表掃描。下一步就是消除病人信息的全表掃描。
通過住院號進行查詢,應(yīng)該是可以用到建立在住院號上的索引,但這里沒有用到,原因是視圖中對住院號使用了to_char()函數(shù),即:to_char(A.住院號) as 住院號。經(jīng)咨詢醫(yī)院和公司的其他人員,必須使用to_char進行轉(zhuǎn)換,否則LIS的接口程序不能提取病人的信息。要徹底解決此問題,有兩種方式,1、使用基本函數(shù)的索引。2、通知三晶公司修改LIS結(jié)口。但第二種可能性很小。于是決定采用基于函數(shù)的索引。
1、修改init.ora參數(shù)
     query_rewrite_enabled = TRUE
query_rewrite_integrity = TRUSTED
2、創(chuàng)建基于函數(shù)的索引
    create index 病人信息_IX_char住院號 on 病人信息(to_char(住院號)) tablespace zl9patient 
3、由于只有在CBO 下才能使用基于函數(shù)的索引,對”病人掛號記錄”等作分析。
     analyze table 病人掛號記錄 compute statistics for all indexed columns for all indexes
4、改造SQL語句,加入提示字(hints:/*+frist_rows*/強制使用CBO。
調(diào)整后的SQL語句執(zhí)行計劃:
SELECT STATEMENT, GOAL = FIRST_ROWS                    Cost=87   Cardinality=74 Bytes=12876
 VIEW       Object owner=ZLHIS         Object name=PATIENTINFO     Cost=87   Cardinality=74 Bytes=12876
     TABLE ACCESS BY INDEX ROWID Object owner=ZLHIS         Object name=病人信息     Cost=2      Cardinality=3    Bytes=129
         INDEX RANGE SCAN        Object owner=ZLHIS         Object name=病人信息_IX_CHAR住院號          Cost=1      Cardinality=3   
        TABLE ACCESS BY INDEX ROWID     Object owner=ZLHIS         Object name=病案主頁     Cost=1         ……………..
          TABLE ACCESS BY INDEX ROWID Object owner=ZLHIS         Object name=病人信息     Cost=2      Cardinality=9    Bytes=387
           INDEX RANGE SCAN    Object owner=ZLHIS         Object name=病人信息_IX_CHAR住院號          Cost=1      Cardinality=9   
      ……………………..
       TABLE ACCESS BY INDEX ROWID       Object owner=ZLHIS         Object name=病人掛號記錄      Cost=3      Cardinality=487793         Bytes=4390137
        INDEX RANGE SCAN          Object owner=ZLHIS         Object name=病人掛號記錄_IX_門診號     Cost=2      Cardinality=487793
      TABLE ACCESS BY INDEX ROWID         Object owner=ZLHIS         Object name=部門表         Cost=1      Cardinality=164         Bytes=3280
       INDEX UNIQUE SCAN Object owner=ZLHIS         Object name=部門表_PK           Cardinality=164       
     TABLE ACCESS BY INDEX ROWID Object owner=ZLHIS         Object name=人員表         Cost=1      Cardinality=491        Bytes=8347
      INDEX UNIQUE SCAN   Object owner=ZLHIS         Object name=人員表_UQ_姓名                  Cardinality=491       
經(jīng)過調(diào)整,LIS系統(tǒng)提取病人信息的語句,速度得到了很大的提高,大概在1秒左右。此至問題解決。
 
 
來頂一下
返回首頁
返回首頁
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
欄目更新
    欄目熱門