ODAC (V9.5.15) 學習筆記(二十)大數據量獲取處理


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;

效果基本滿意


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM