|
Posted on 2006-02-22 10:21 天空蒼茫 閱讀(325) 評論(0) 編輯 收藏 所屬分類: jsp學(xué)習(xí)
開發(fā)一個注重性能的JDBC應(yīng)用程序不是一件容易的事. 當(dāng)你的代碼運(yùn)行很慢的時候JDBC驅(qū)動程序并不會拋出異常告訴你。
本系列的性能提示將為改善JDBC應(yīng)用程序的性能介紹一些基本的指導(dǎo)原則,這其中的原則已經(jīng)被許多現(xiàn)有的JDBC應(yīng)用程序編譯運(yùn)行并驗(yàn)證過。 這些指導(dǎo)原則包括: 正確的使用數(shù)據(jù)庫MetaData方法 只獲取需要的數(shù)據(jù) 選用最佳性能的功能 管理連接和更新
以下這些一般性原則可以幫助你解決一些公共的JDBC系統(tǒng)的性能問題.
使用數(shù)據(jù)庫Metadata方法
因?yàn)橥ㄟ^ResultSet對象生成的Metadata方法與其它的JDBCB方法相比是較慢的, 經(jīng)常的使用它們將會削弱系統(tǒng)的的性能. 本節(jié)的指導(dǎo)原則將幫助你選擇和使用meatdata時優(yōu)化系統(tǒng)性能.
少用Metadata方法
與其它的JDBC方法相比, 由ResultSet對象生成的metadata對象的相對來說是很慢的. 應(yīng)用程序應(yīng)該緩存從ResultSet返回的metadata信息,避免多次不必要的執(zhí)行這個操作.
幾乎沒有哪一個JDBC應(yīng)用程序不用到metadata,雖然如此,你仍可以通過少用它們來改善系統(tǒng)性能. 要返回JDBC規(guī)范規(guī)定的結(jié)果集的所有列信息, 一個簡單的metadata的方法調(diào)用可能會使JDBC驅(qū)動程序去執(zhí)行很復(fù)雜的查詢甚至多次查詢?nèi)ト〉眠@些數(shù)據(jù). 這些細(xì)節(jié)上的SQL語言的操作是非常消耗性能的.
應(yīng)用程序應(yīng)該緩存這些metadata信息. 例如, 程序調(diào)用一次getTypeInfo方法后就將這些程序所依賴的結(jié)果信息緩存. 而任何程序都不大可能用到這些結(jié)果信息中的所有內(nèi)容,所以這些緩存信息應(yīng)該是不難維護(hù)的.
避免null參數(shù)
在metadata的方法中使用null參數(shù)或search patterns是很耗時的. 另外, 額外的查詢會導(dǎo)致潛在的網(wǎng)絡(luò)交通的增加. 應(yīng)盡可能的提供一些non-null的參數(shù)給metadata方法.
因?yàn)閙etadata的方法很慢, 應(yīng)用程序要盡可能有效的調(diào)用它們. 許多應(yīng)用程序只傳遞少量的non-null參數(shù)給這些方法.
例如:
ResultSet WSrs = WSc.getTables (null, null, "WSTable", null);
應(yīng)該這樣:
ResultSet WSrs = WSc.getTables ("cat1", "johng", "WSTable", "TABLE");
在第一個getTables()的調(diào)用中, 程序可能想知道表'WSTable'是否存在. 當(dāng)然, JDBC驅(qū)動程序會逐個調(diào)用它們并且會解譯不同的請求. JDBC驅(qū)動程序會解譯請求為: 返回所有的表, 視圖, 系統(tǒng)表, synonyms, 臨時表, 或存在于任何數(shù)據(jù)庫類別任何Schema中的任何別名為'WSTable'的對象.
第二個getTables()的調(diào)用會得到更正確的程序想知道的內(nèi)容. JDBC驅(qū)動程序會解譯這個請求為: 返回當(dāng)前數(shù)據(jù)庫類別中所有存在于'johng'這個schema中的所有表.
很顯然, JDBC驅(qū)動程序處理第二個請求比處理第一個請求更有效率一些.
有時, 你所請求信息中的對象有些信息是已知的. 當(dāng)調(diào)用metadata方法時, 程序能傳送到驅(qū)動程序的的任何有用信息都可以導(dǎo)致性能和可靠性的改善.
使用'啞元'(dummy)查詢確定表的特性
要避免使用getColumns()去確定一個表的特性. 而應(yīng)該使用一個‘啞元’查詢來使用getMetadata()方法.
請考慮這樣一個程序, 程序中要允許用戶選取一些列. 我們是否應(yīng)該使用getColumns()去返回列信息給用戶還是以一個'啞元'查詢來調(diào)用getMetadata()方法呢?
案例 1: GetColumns 方法
ResultSet WSrc = WSc.getColumns (... "UnknownTable" ...); // getColumns()會發(fā)出一個查詢給數(shù)據(jù)庫系統(tǒng) . . . WSrc.next(); string Cname = getString(4); . . . // 用戶必須從反復(fù)從服務(wù)器獲取N行數(shù)據(jù) // N = UnknownTable的列數(shù) | 案例 2: GetMetadata 方法
// 準(zhǔn)備'啞元'查詢 PreparedStatement WSps = WSc.prepareStatement ("SELECT * from UnknownTable WHERE 1 = 0"); // 查詢從來沒有被執(zhí)行,只是被預(yù)儲 ResultSetMetaData WSsmd=WSps.getMetaData(); int numcols = WSrsmd.getColumnCount(); ... int ctype = WSrsmd.getColumnType(n) ... // 獲得了列的完整信息 | 在這兩個案例中, 一個查詢被傳送到服務(wù)器. 但在案例1中, 查詢必須被預(yù)儲和執(zhí)行, 結(jié)果的描述信息必須確定(以傳給getColumns()方法), 并且客戶端必須接收一個包含列信息的結(jié)果集. 在案例2中, 只要準(zhǔn)備一個簡單的查詢并且只用確定結(jié)果描述信息. 很顯然, 案例2執(zhí)行方式更好一些.
這個討論有點(diǎn)復(fù)雜, 讓我們考慮一個沒有本地化支持prepared statement的DBMS服務(wù)器. 案例1的性能沒有改變, 但案例2中, 因?yàn)?啞元'查詢必須被執(zhí)行而不是被預(yù)儲使得它的性能增強(qiáng)了一些. 因?yàn)椴樵冎械腤HERE子句總是為FALSE, 查詢在不用存取表的數(shù)據(jù)情況的下會生成沒有數(shù)據(jù)的結(jié)果集. 在這種情況下,第二種方式當(dāng)然比第一種方式好一些.
總而言之,總是使用ResultSet的metadata方法去獲取列信息,像列名,列的數(shù)據(jù)類型,列的數(shù)據(jù)精度和長度等. 當(dāng)要求的信息無法從ResultSet的metadata中獲取時才去用getColumns()方法(像列的缺省值這些信息等)。
|