標籤:
ODAC擷取資料的效率比較高,在Web程式中希望能夠更快擷取第一頁的資料時,可以有幾種方式:
1、在資料庫中進行分頁處理;
2、擷取所有資料,只是快速返回第一頁資料。
第一種方案對應用伺服器資源消耗最小,對資料庫消耗略大,在客戶需要對全資料進行靈活過濾、尋找、統計時就有些不夠用了,另外對耗時較大的SQL查詢就不如第二種方案速度快,對資料庫壓力也要大些,並且需要編寫程式來完成。在Delphi下我考慮使用第二種方案,尤其是在使用uniGUI+ODAC配合使用時。第二種方案對應於伺服器記憶體壓力略大,並且要求快速擷取第一頁資料,為此做了個實驗:
1、單表中有24萬條記錄
2、使用一次性擷取全部記錄,並放在伺服器記憶體中,由uniGUI的網格進行自動分頁處理。
3、非一次性擷取全部記錄時,需要快速擷取第一頁資料,將TOraQuery組件的FetchRows設定與TUniDBGrid組件的WebOptions.PageSize一致(不是必須的,只是覺得這樣對顯示第一頁更有效率些),再通過啟動一個線程,在後台通過TOraQuery組件的FetchAll屬性設為True來擷取全部資料。TOraQuery的資料量發生變化後,在TUniDBGrid組件中滾動任意記錄都會觸發記錄數與分頁數的自動更新,所以不需要在擷取全部資料後重新整理網格。
代碼如下:
procedure TMainForm.UniButton11Click(Sender: TObject);var d : DWORD;begin //計時 d := GetTickCount; //每個資料包擷取的記錄數,建議與網格的每頁數保持一致 UniMainModule.OraQuery7.FetchRows := UniDBGrid7.WebOptions.PageSize; //是否一次性擷取 UniMainModule.OraQuery7.FetchAll := UniCheckBox7.Checked; //開啟表,如果是非一次性擷取,則中獲得了第一個資料包的記錄數 UniMainModule.OraQuery7.Open; //花費時間 UniLabel17.Caption := Format(‘%d ms‘, [GetTickCount - d]); //開啟線程擷取 if not UniCheckBox7.Checked then TFetchThread.Create(UniMainModule.OraQuery7);end;
UniCheckBox7.Checked決定了是否採用一次性擷取的選項,實驗顯示:
1、一次性擷取資料模式,顯示第一頁花費了3000ms左右時間,記憶體佔用約180M,關閉資料集後記憶體減少為10M左右,說明記憶體釋放非常乾淨。
2、非一次性擷取資料模式,顯示第一頁花費了約20ms左右時間,後台讀取資料沒有影響前端資料的展示、滾動等操作,最終記憶體佔用與關閉後釋放同一次性擷取模式。
後台擷取資料的線程代碼如下:
TFetchThread = class(TThread) private FDataSet : TOraQuery; public procedure Execute; override; constructor Create(ADataSet : TOraQuery); end;
{ TFetchThread }constructor TFetchThread.Create(ADataSet: TOraQuery);begin FDataSet := ADataSet; FreeOnTerminate := True; inherited Create;end;procedure TFetchThread.Execute;begin inherited; if Assigned(FDataSet) then begin FDataSet.FetchAll := True; while not FDataSet.Fetched do Sleep(10); MainForm.Caption := ‘refresh‘; end;end;
效果基本滿意
ODAC (V9.5.15) 學習筆記(二十)大資料量擷取處理