優化你的PowerBuilder程序
一、處理 SQL 語句
1、緩沖 SQL 語句
SQLCACHE = n
n 表示裝入緩沖區的 SQL 語句數量(缺省為0)。
例如:
dw_1.SetTransObject(sqlca)
SQLCA.dbParm = "SQLCache = 0"
dw_1.retrieve()
如果將上例的 "SQLCache = 0" 改為 "SQLCache = 25",此句的執行效率將提高五分之一左右。但應注意緩沖區的大小,否則也將影響程序執行的性能。
注:此方法對用 ODBC 和 ORACLE 連接的數據庫非常有效。
2、捆綁變量
請看下例:
SQLCA.DBPARM = "DISABLEBIND=1"
INSERT INTO DA_DH VALUES("1","河南0")
INSERT INTO DA_DH VALUES("2","河南1")
INSERT INTO DA_DH VALUES("3","河南2")
INSERT INTO DA_DH VALUES("4","河南3")
INSERT INTO DA_DH VALUES("5","河南4")
INSERT INTO DA_DH VALUES("6","河南5")
這里未使用捆綁變量,再插入時 PB 將重新處理每個帶有新值的SQL語句。
如果將上例改為:
SQLCA.DBPARM = "DISABLEBIND=0"
INSERT INTO DA_DH VALUES("1","河南0")
INSERT INTO DA_DH VALUES("2","河南1")
INSERT INTO DA_DH VALUES("3","河南2")
INSERT INTO DA_DH VALUES("4","河南3")
INSERT INTO DA_DH VALUES("5","河南4")
INSERT INTO DA_DH VALUES("6","河南5")
則系統將把 INSERT 語句按如下格式進行處理:
INSERT INTO DA_DH VALUES(?,?)
其中 "?" 稱為占位符。系統性能將有所增強。
3、用數據窗口代替 SQL 語句
通常,為了獲得某些數據,采用數據窗口和 SQL 語句都是可行的,但是PB 對數據窗口和 SQL 語句采用不同的處理機制,因此,具有不同的效率。
例:為里檢索電話檔案中的用戶名,可以利用 SQL 語句,將所有的數據檢索到一個多行編輯中,也可以檢索到一個數據窗口中。
如果使用第一種方法:
首先定義一個游標:
DECLARE CUR CURSOR FOR
SELECT "DA_DH"."HM"
FROM "DA_DH";
然后可以:
STRING stxt[],st
int li
open cur
do li = li + 1
fetch cur
into :stxt[li] ;
st=st+stxt[li] + "~r~n"
loop while stxt[li]<>""
close cur;
mle_1.txt = st
也可以使用第二種方法:
dw_1.settransobject(sqlca)
dw_1.retrieve()
利用 POWERBUILDER PROFILER 工具進行檢查,對比兩種方法所需時間如下
方法 所需時間 (百分之一秒)
SQL 語句 100.9857
數據窗口 49.0133
由于數據窗口或DATASTORE使用了標準的內嵌代碼,而不是由開發人員進行全部編碼,同時編譯執行的速度比解釋執行的速度快的多,因此在開發過程中應盡量使用數據窗口和DATASTORE.即使是必須用SQL語句的時候,也應該盡量將它們定義為存儲過程(特別是在多用戶的環境中),以提高應用程序的性能.
二、數據窗口的編程和執行
數據窗口是PB最值得被稱道的, 其具有如下特點:
1. 多種顯示方式.
2. 多種編輯方式.
3. 使用方法簡單.
4. 具有多種報表形式.
5. 可實現屏幕滾動.
6. 可實現數據的有效性校驗.
7. 執行性能顯著提高.
8. 編程工作變少.
9. 可以在數據窗口內部實現數據哭的更新.
下面, 我將介紹一些用于提高數據窗口性能的技術.
1. 減少連接數據庫的次數
連庫操作是非常影響執行速度的操作. 因此在程序中,一旦與數據庫連接后就應當盡量保持與數據庫的連接, 減少連接數據庫的次數.PowerBuilder 提供里兩個函數來建立數據窗口與事務對象的連接:
SetTrans()
SetTransObject()
在程序中應當盡量使用 SETTRANSOBJECT(), 因為SETTRANS() 函數在每次調用 RETRIEVE(), UPDATE() 等函數之后, 都要執行數據庫的連接和斷開操作.
2. 下拉數據窗口與表的連接
對于數據庫服務器來說, 表的連接操作是一項非常大的開銷, 而 POWERBUILDER 提供的下拉數據窗口在某些情況下可以代替表的連接操作.例如, 為了在數據窗口上顯示用戶的電話號碼和姓名:如果用表的連接的方法, 數據窗口對應的 SQL 語句應是這樣的:
SELECT "DA_DH"."DHHM","DA_HTH"."DWM"
FROM "DA_HTH", "DA_DH"
WHERE ("DA_HTH"."DHHM"="DA_DH"."DHHM")
同樣的程序可用下拉數據窗口來完成, 這里不再具體介紹.但是, 應當注意, 以上兩種方法究竟哪一種數據更快, 與表的結構, 表的數量, 連接的方法等均有關系, 應當具體分析.
3. 共享數據
在一個應用程序中, 某些數據需要頻繁的使用, 如果在每次使用時都從數據庫中進行檢索, 則需占用大量的服務器資源和網絡資源. 為了減少開銷, 可以在客戶端對這些數據只進行一次檢索, 然后允許其它任務共享這些數據.
例如, 如果有兩個數據窗口, 都需要從第三方表中檢索出用戶的電話號碼, 且此列用下拉數據窗口給出. 如果每次都對電話號碼進行檢索, 則性能較低. 因此, 可以單獨建立一個關于電話號碼的數據窗口. 在每次打開窗口時, 首先將電話號碼檢索到此數據窗口中, 然后另外兩個數據窗口中關于電話號碼的下拉數據窗口可以共享此數據窗口中的數據.
在窗口的 OPEN 事件中編寫如下程序:
dw_1.settransobject(sqlca)
dw_2.settransobject(sqlca)
dw_3.settransobject(sqlca)
// 檢索 dw_1
dw_1.retrieve()
// 使 DW_2 的下拉數據窗口共享 DW_1
datawindowchild child1
dw_2.getchild('dhhm',child1)
child1.settransobject(sqlca)
dw_1.sharedata(child1)
// 使 DW_2 的下拉數據窗口共享 DW_1
datawindowchild child2
dw_3.getchild('dhhm',child2)
child2.settransobject(sqlca)
dw_1.sharedata(child1)
使用這種方法, 避免了各個數據窗口間物理的拷貝數據, 因此減少了空間上的開銷,提高了應用程序的綜合性能.
原文轉自:http://www.anti-gravitydesign.com