盡可能用預先排序的數據
ADONET對象模式使我們可以很容易地實現排序你可以創建一個DataView對象並設置其Sort屬性ADONET runtime查看新的排序表達式並為視圖重編索引該步驟是在內存中實現的但速度並不快排序的花費很高更重要的是它並不是個線性操作(linear operation)對一組數據進行排序需要n*log(n)的計算成本就是說隨著需要排序的條目數量的增加直線增加的成本是很大的因此你應該限制應用程序中的排序盡可能地運用預先排序的數據在Web應用程序中動態排序對性能的影響是相當大的既然如此你就應該設計應用程序限制對動態排序的需求並依賴在數據庫服務器中寫死的算法除非你在用應用程序的一個可以使復雜性低於n*log(n)極限的特殊的功能否則避免運用手工排序算法因為這種算法可能比系統中的算法更糟
ADOX可以幫你得到並改變Schema信息
ADONET並沒有為得到並管理schema信息提供一個完全的對象模式你應該用ActiveX Data Objects Extensions for Data Definition Language and Security (ADOX)或用每個數據庫提供的本地功能來得到並改變Schema信息ADOX是ADO對象的一個擴展它包括用來創建和修改Schema的對象你可以編寫適用於各種數據源的代碼(不管本地語法有什麼不同)因為ADOX是管理schema的一個基於對象的方法
你可以用一個data reader對象來讀(不是設置)簡單的schema信息所有的data reader類(OleDbDataReaderSqlDataReaderOracleDataReader)都提供了一個GetSchemaTable方法該方法可以讀取查詢到的列的元數據信息GetSchemaTable返回一個DataTable對象(格式是每列一行)和固定的一組包含信息的列返回的元數據可以分成三類列元數據數據庫特征和列屬性返回的列可以是AllowDBNullIsAutoIncrementColumnNameIsExpressionIsReadonly和NumericPrecision等在MSDN資料中有完整的列表(見附加資源)
在調用ExecuteReader時如果你執行KeyInfo命令那麼GetSchemaTable方法就可以返回更精確的數據你可以將KeyInfo行為同缺省的行為結合起來執行一個單獨的命令並得到schema和數據
reader = cmd
ExecuteReader( _
CommandBehavior
KeyInfo Or _
CommandBehavior
CloseConnection)
只有執行KeyInfoIsKeyBaseTableNameIsAliasedIsExpression和IsHidden字段的值才能被正確返回如果執行KeyInfo關鍵的列(如果有)通常是添加在結果集的底部的但不給它們返回數據
用一個派生的類和自定義的串行化來節省空間
只有兩個ADONET對象是被標記為可串行化的——DataTable和DataSetNET Framework中的串行化是通過formatter對象來完成的它們可以將一個對象實例保存到一個二進制或一個SOAP流(stream)中NET formatter用Reflection來提取任何必要的信息然而如果這個類實現了ISerializable接口那麼NET formatter就會給接口的方法讓步讓它們負責拷貝需要串行化到一個內存緩沖器中的所有的信息DataTable和DataSet類都通過ISerializable接口支持串行化
如果你將一個DataTable或一個DataSet串行到一個二進制(binary stream)中你應該可以得到非常緊湊的輸出結果雖然你得到的結果文件是最小的但遺憾的是它實際上並不小荒謬的是你保存到一個二進制的DataSet比你用WriteXml方法保存到XML的同樣的DataSet要大很多
要解釋這種情況我們需要來看看ADONET對象是用什麼方式被串行起來的在串行一個DataSet對象時它將基於XML的DiffGram表示法保存在formatter的緩沖器中在串行一個DataTable時它首先創建了一個臨時的DataSet對象將它定義為它的parent然後作為一個DiffGram串行起來
一個DiffGram是一個XML流它提供了一個DataSet中表和行的有狀態的表示法一個DiffGram文件是很詳細的有些冗長DiffGram包含當前的數據以及被修改的行和未解決的錯誤的初始值當我們保存一個DataSet或一個DataTable時所有這些信息就會被傳遞給serializer被串行化的對象總是包含XML數據因此即使當輸出流是二進制的時最後的輸出結果仍然會很大
你可以創建一個繼承DataTable或DataSet的新的可串行化的類來解決這個問題並且更有效地保存ADONET對象你必須用<Serizlizable()>屬性來標記新類即使父類是可以串行化的實際上串行性(serizlizability)並不是一個可以自動繼承的類屬性你從DataTable或DataSet構建的新類也可以實現ISerializable接口當然你可以為新類選擇一個不同的串行化方案一個簡單而有效的方法就是將DataTable類的所有成員映射到數組和值成員中
運用一個派生的類和一個自定義的串行化方案可以為一個DataSet對象節省多達%的磁盤空間節省的空間的比率取決於DataSet中的數據類型你的數據越基於文本節省的空間越多然而運用二進制的BLOB字段只可以節省大約%的空間(下載一個完整的例子)
選擇一個適合你的數據的分頁機制
DataGrid服務器控件使我們可以更容易地在Web應用程序中以長度可變的頁面來顯示數據了該控件有綁定和格式化功能它可以接受一個ADONET數據對象並為浏覽器生成HTML代碼出於性能的原因在頁面的視圖狀態DataGrid並沒有緩存數據源的內容因此當返回頁面時你就必須填充grid要實現這一點可以用兩種方法在Web服務器上將數據源作為整體或一部分緩存起來然後讀回或者對每個請求從物理數據庫加載所需的記錄如果你選擇第一種方法那麼數據就從存儲中只被讀取一次保存在一個緩存中並為以後的postback事件讀回我們通常用內存中的全局對象(如Session或Cache)來保存這個數據我們用DataSet來搜集所有需要的數據並將它保存在內存中將一個DataSet對象保存在Session中同ADO中的線程含義並不一樣但是通過減少Web服務器可用的內存仍可以影響可擴展性
如果要顯示的數據是特定於session的那麼在每次返回頁面時加載記錄頁面就比用一個DataSet和ASPNET全局對象來緩存數據要好編寫得很好的SQL代碼可以將結果集分成許多頁再加上DataGrid控件內置的自定義分頁機制我們就可以得到最佳的解決方案來保持ASPNET應用程序的可擴展性和良好的性能了
[] [] [] []
From:http://tw.wingwit.com/Article/program/net/201311/15152.html