zoukankan      html  css  js  c++  java
  • 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;

    效果基本满意

  • 相关阅读:
    c++继承中的内存布局
    函数调用的原理4点:函数产生名不同,压栈顺序不同,不应由客户清理,客户清理则可执行文件大小更大(许多参考文章,有汇编解释)
    黑马程序员:Java基础总结----JavaBean 内省
    汇编语言理解指针(指针就是汇编的间接寻址,其实就是一个简单方便的运算指令,计算完毕直接就赋值,不是从内存中去取值后赋值)
    设计项目时候的几个小标记
    SendTextMessage如何打开记事本并显示指定内容
    汇编语言---call和ret指令
    汇编语言转移指令规则汇总
    SharePoint Access Service-PowerShell
    对所有CPU寄存器的简述(16位CPU14个,32位CPU16个)
  • 原文地址:https://www.cnblogs.com/ChinaEHR/p/4480482.html
Copyright © 2011-2022 走看看