本文從以下四個部分加以說明: 適當地使用數據庫的元數據方法 檢索需要的數據 選擇優化性能的功能 治理連接和數據更新 適當地使用數據庫的元數據方法 1.1. 盡量少用元數據方法 由于元數據方法執行速度比較慢,故要盡量少用元數據方法。由于調用元數據方法產生結果集需要大量的開銷,由元數據方法產生的結果集應該緩存起來,而不是多次執行查詢,這樣可以提供JDBC的性能。例如在應用中你調用了getTypeInfo一次,你就應該將結果集緩存起來,共應用再次使用。 1.2. 避免查詢模式 給元數據提供null參數或查詢模式將會產生耗時的查詢。同時,由于一些不需要的數據通過網絡傳遞,導致網絡流量的增大,降低整個系統的性能。由于元數據方法執行比較慢,所以盡可能地給它提供非null參數和高效地調用它。而我們的應用常出現這樣的現象: ResultSet WSrs = WSc.getTables (null, null, "WSTable", null); 應該改成: ResultSet WSrs = WSc.getTables ("cat1", "johng", "WSTable", "TABLE"); 顯然,在第一個getTables()調用中,應用可能需要知道WSTable表是否存在。當然, JDBC驅動按字面上的調用與解析請求不同。JDBC是這樣解析請求的:返回所有的名稱叫“WSTable”的表,視圖,系統表,同義詞,零時表,或在任何數據庫目錄中數據庫的模式存在的別名。 第二個getTables()的調用更準確地反映了應用需要知道什么。JDBC這樣解析這個請求:返回所有名叫“WSTable”存在與當前目錄中模式為“johng’的所有表。顯然,JDBC驅動處理第二個請求要比處理第一個請求來得更有效。 給元數據方法提供的信息越多,你得到的信息的準確性和性能也越高。 1.3. 使用啞元查詢來確定表的特征 避免使用getColumns()確定一個表的特征。用getMedata()啞元查詢替換之??紤]一個容許用戶選擇列的應用。應用應該用getColumns()返回用戶列的信息還是預備一個啞元查詢并調用getMetadata()呢? 情形1:getColumns方法 ResultSet WSrc = WSc.getColumns (... "UnknownTable" ...);// This call to getColumns() will generate a query to// the system catalogs... possibly a join// which must be PRepared, executed, and prodUCe// a result set. . .WSrc.next();string Cname = getString(4);. . .// user must retrieve N rows from the server// N = # result columns of UnknownTable// result column information has now been oBTained 情形2:getMetadata方法 // prepare dummy queryPreparedStatement WSps = WSc.prepareStatement ("SELECT * from UnknownTable WHERE 1 = 0");// query is never executed on the server - only preparedResultSetMetaData WSsmd=WSps.getMetaData();int numcols = WSrsmd.getColumnCount();...int ctype = WSrsmd.getColumnType(n)...// result column information has now been obtained 在兩個情形中,查詢被送到服務器上。但在情形1中,查詢必須被預備和執行,結果描述信息必須被簡潔地表達,并且結果集必須送到客戶端。在情形2中,一個簡單的查詢必須預備并且僅有結果描述信息被簡潔地描述。顯然,情形2是更好的性能模式。 這多少有些把這個討論復雜化了,讓我們考慮一個不支持本地預備SQL語句的數據庫。情形1的性能沒有變,但由于啞元查詢必須被求值而不是僅僅預備,因此情形2的性能稍微有些增加。因為查詢語句的Where子句計算結果總是FALSE,因此查詢沒有產出結果行和不存取表數據的執行。在這個情形下,方法2仍然要比方法1做的好。 總之,總是使用結果集元數據檢索表列信息,如列名,列數據類型和列精度和數值范圍。當被請求的信息不能從結果記錄集(例如,表列默認值)獲取的時候,僅僅使用getColumns()方法。 2. 檢索需要的數據 2.1. 檢索長數據 除非必要,由于檢索長數據會造成網絡資源緊張而降低性能。通常大多數用戶不需要看到長數據,假如用戶需要看這些數據,應用再去檢索。 我們的代碼中長出現這樣的代碼:select * from <table name> …假如選擇的表中有長數據列,那這個查詢的性能將會非常糟糕。再說,表中的所有數據項你都需要嗎?假如不需要,為什么要讓它們在網絡上傳遞,浪費網絡資源? 例如,看看下邊的JDBC代碼: ResultSet rs = stmt.executeQuery ( "select * from Employees where SSID = '999-99-2222'");rs.next();string name = rs.getString (4); JDBC不是智能的。當你這樣寫代碼的時候,它根本就不知道你真正需要那些列,它把所有的都返回當然是情理之中的事情了,所以開發的時候就勞煩把需要的列在Select語句中指明。假如Employees表中有照片之類的長數據字段,系統的性能之低就可想而知了。 盡管有方法getClob()和getBlod()支持這種長數據字段的檢索,但并不是每個數據庫都支持它。所以記住:需要長數據的時候再去讀它。 2.2. 減少檢索到的數據的大小 有時候,長數據必須被檢索。在這種情況下,大多數用戶可能不需要在屏幕看到100k(或更多)的正文。 為了減少網絡流量和提高性能,你可以通過調用setMaxRows(),setMaxFieldSize(),以及與驅動相關的setFetchSize()方法把檢索到的數據大小減少到可治理的范圍之內。另一個減少檢索到的數據大小的方法是減少列的數量。假如驅動答應你定義包尺寸,使用最小的包尺寸將會滿足你的需要。 記住:注重只返回你需要的行和列。假如你返回了五列而你只需要兩列,性能就降低了??非凡是不需要的結果中包含了長數據。 2.3. 選擇正確的數據類型 檢索和送出某種數據的類型的開銷是很昂貴的。當設計數據庫模式時,選擇能最有效處理的數據類型。例如,整型要比浮點數和小數數據要快。浮點數根據數據庫非凡的格式定義,通常是壓縮格式。為了能被數據庫通訊協議處理,這些數據必須被解壓后再轉換成不同的格式。 2.4. 檢索記錄集 由于數據庫系統對滾動游標的有限支持,大多數JDBC驅動不能實現滾動游標。除非你確定數據庫支持滾動記錄集(例如,rs),否則不要調用rs.last()和rs.getRow()去得到記錄集有多少行。對模擬滾動游標的JDBC驅動而言,調用rs.last()會導致驅動為了到最后一行而通過網絡檢索所有的數據。可以替代的方法是你可以通過記錄集枚舉記錄行數,或者通過提交在SELECT語句中一個帶有COUNT列的查詢得到行數。