1. gzyueqian
      18529173453
      首頁 > 新聞中心 > > 正文

      J2EE應用中,提升數據訪問層的性能

      更新時間: 2007-06-07 17:48:28來源: 粵嵌教育瀏覽量:830

        本文從以下四個部分加以說明:
        適當地使用數據庫的元數據方法
        檢索需要的數據
        選擇優化性能的功能
        管理連接和數據更新
        適當地使用數據庫的元數據方法

        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列的查詢得到行數。

      免費預約試聽課

      亚洲另类欧美综合久久图片区_亚洲中文字幕日产无码2020_欧美日本一区二区三区桃色视频_亚洲AⅤ天堂一区二区三区

      
      

      1. 午夜影视在线播放免费人成 | 色在线中文字幕大 | 亚洲视频在线观看 | 亚洲最新午夜福利网址 | 中文字字幕在线中文乱码品 | 日韩一区精品视频在线观看蜜桃 |