l 總的考慮方向
1) 根據數據使用的方式來設計數據訪問層
2) 緩存數據,避免不必要的操作
3) 使用服務帳戶進行連接
4) 必要時連接,盡早釋放
5) 關閉可關閉的資源
6) 減少往返
7) 僅返回需要的數據
8) 選擇適當的事務類型
9) 使用存儲過程
根據性能、可維護性、及實現難度來決定跨層數據傳遞的方式
2 具體實現
1)選用合適的Data PRovider
應盡量使用專用的Data Provider,下面是一個性能比較表
由上圖中可以看出SqlClient的速度是最快的,其主要原因是其他的數據提供者都經過的幾個層次的轉換,如下圖
從圖中可以看出,SqlClient直接訪問DB Netlib而其他的數據提供者都經過了兩層轉換,因此,在設計多層應用的時候,并不是層次越多越好,而是應該在可擴展性與性能間取折中,增加層次是會降低性能的。
1) 數據庫連接
i. 在方法中打開和關閉連接,即不要在類的構造函數中打開連接,在類的析構函數中關閉連接。
ii. 使用完連接明確地關閉。因為有連接池的支持,關閉連接只是將連接放回連接池,并不是真正銷毀,不會帶來性能開銷,而會增加連接池中可用連接,提升性能。
iii. 當使用DataReaders時,指定CommandBehavior.CloseConnection
iv. 當使用Fill()與Updata()時,不要手動打開連接。因為DataAdapter會自動開啟連接,但是如果是Command則需要手動開啟。
v. 避免檢查OleDbConnection的State屬性,其性能開銷相當大。
vi. 使用連接池。這種方法可以大幅度提高性能。默認的情況下,通過SqlClient連接數據庫時,會使用連接池,另可以通過連接字符串來控制連接池的最大值,最小值,以及是否開啟連接池。
2) SQL指令
i. 檢查SQL的輸入,并使用參數,直接使用字符連接容易遭受注入式攻擊。
ii. 僅返回需要的行和例
iii. 對大的數據集使用分頁功能
iv. 批次執行SQL,避免多次往返。
v. 如果沒有數據返回則使用ExecuteNonQuery方法
vi. 當返回一個標量時,使用ExecuteScalar方法
vii. 不要在運行時間使用CommandBuilder,盡管很省事,但是開銷很大。
3) 存儲過程
i. 盡量使用存儲過程
ii. 對于OleDbCommand,指令類型為CommandType.Text
iii. 使用SqlCommand,指令類型為CommandType.StoredProcedure
iv. 盡可能使用輸出參數
v. 考慮在SQL Server中SET NOCOUNT ON,即關閉SQL Server的記數功能。
4) 事務
5) 使用參數
i. 在存儲過程上使用參數
ii. 創建參數并指定類型
iii. 可將參數對象進行緩存
6) DataReader和DataSet
i. DataReader對象需要關閉
ii. 用DataReader時應,使用CommandBehavior.CloseConnection關閉連接
iii. DataReader應用在只讀、只向前翻滾的數據訪問場景
iv. 只想快速訪問數據,不需要緩存功能應使用DataReader
DataSet在需要數據緩存,并在不同層間傳遞時使用。它可以存放多個結果集,可以在離線的情況下自由定位,查找數據。
總的來說,提高性能會降低可擴展性,以及維護難度,應在滿足功能與非功能需求的情況下提高性能,另應在設計時就考慮性能,好的設計在性能上的提升比差的設計后期再修改要好得多。
新聞熱點
疑難解答