表现 – BDE与ADO在德尔福

前端之家收集整理的这篇文章主要介绍了表现 – BDE与ADO在德尔福前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
请注意下面的编辑更多信息,以及可能的解决方

我们最近修改了一个大型Delphi应用程序来使用ADO连接和查询而不是BDE连接和查询.由于这种变化,表现已经变得可怕了.

我已经分析了应用程序,并且瓶颈似乎在实际调用TADOQuery.Open.换句话说,从代码角度来看,除了重组应用程序以减少实际使用的数据之外,还没有太多的工作来改进这一点.

有没有人有关于如何提高ADO连接的Delphi应用程序的性能的建议?我已经尝试了suggestions given here,几乎没有任何影响.

为了给出性能差异的想法,我对同样大的操作进行了基准测试:

>在BDE下:11秒
>在ADO下:73秒
>在该文章引用的更改后的ADO下:72秒

我们正在客户端 – 服务器环境中使用Oracle后端.本地计算机每个维护与数据库的单独连接.

为了记录,连接字符串如下所示:

const
  c_ADOConnString = 'Provider=OraOLEDB.Oracle.1;Persist Security Info=True;' +
                    'Extended Properties="plsqlrset=1";' +
                    'Data Source=DATABASE.DOMAIN.COM;OPTION=35;' +
                    'User ID=******;Password=*******';

回答zendar提出的问题:

我在Windows Vista和XP上使用Delphi 2007.

后端是Oracle 10g数据库.

如连接字符串所示,我们使用OraOLEDB驱动程序.

我的基准机器上的MDAC版本是6.0.

编辑:

在BDE下,我们有很多代码看起来像这样:

procedure MyBDEProc;
var
  qry: TQuery;
begin
  //fast under BDE,but slow under ADO!!
  qry := TQuery.Create(Self);
  try
    with qry do begin
      Database := g_Database;
      sql.Clear;
      sql.Add('SELECT');
      sql.Add('  FIELD1');
      sql.Add(',FIELD2');
      sql.Add(',FIELD3');
      sql.Add('FROM');
      sql.Add('  TABLE1');
      sql.Add('WHERE SOME_FIELD = SOME_CONDITION');
      Open;
      //do something
      Close;
    end;  //with
  finally
    FreeAndNil(qry);
  end;  //try-finally
end;  //proc

但是我们发现在ADO下调用sql.Add实际上是非常昂贵的,因为每次更改CommandText时都会触发QueryChanged事件.所以用这个代替以上更快:

procedure MyADOProc;
var
  qry: TADOQuery;
begin
  //fast(er) under ADO
  qry := TADOQuery.Create(Self);
  try
    with qry do begin
      Connection := g_Connection;
      sql.Text := ' SELECT ';
        + '   FIELD1 '
        + ',FIELD2 '
        + ',FIELD3 '
        + ' FROM '
        + '  TABLE1 '
        + ' WHERE SOME_FIELD = SOME_CONDITION ';
      Open;
      //do something
      Close;
    end;  //with
  finally
    FreeAndNil(qry);
  end;  //try-finally
end;  //proc

更好的是,您可以从ADODB.pas中复制TADOQuery,将其重命名为新名称,然后将QueryChanged事件(根据我所知道的)完全没有任何用处.然后使用您的新版本的TADOQuery,而不是本机版本.

type
  TADOQueryTurbo = class(TCustomADODataSet)
  private
    //
  protected
    procedure QueryChanged(Sender: TObject);
  public
    Fsql: TWideStrings;
    FRowsAffected: Integer;
    function Getsql: TWideStrings;
    procedure Setsql(const Value: TWideStrings);
    procedure Open;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    function Execsql: Integer; {for TQuery compatibility}
    property RowsAffected: Integer read FRowsAffected;
  published
    property CommandTimeout;
    property DataSource;
    property EnableBCD;
    property ParamCheck;
    property Parameters;
    property Prepared;
    property sql: TWideStrings read Fsql write Setsql;
  end;
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
constructor TADOQueryTurbo.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Fsql := TWideStringList.Create;
  TWideStringList(Fsql).OnChange := QueryChanged;
  Command.CommandText := 'sql'; { Do not localize }
end;

destructor TADOQueryTurbo.Destroy;
begin
  inherited;
 inherited Destroy;
  FreeAndNil(Fsql);
end;

function TADOQueryTurbo.Execsql: Integer;
begin
  CommandText := Fsql.Text;
  inherited;
end;

function TADOQueryTurbo.Getsql: TWideStrings;
begin
  Result := Fsql;
end;

procedure TADOQueryTurbo.Open;
begin
  CommandText := Fsql.Text;
  inherited Open;
end;

procedure TADOQueryTurbo.QueryChanged(Sender: TObject);
begin
// if not (csLoading in ComponentState) then
//    Close;
// CommandText := Fsql.Text;
end;

procedure TADOQueryTurbo.Setsql(const Value: TWideStrings);
begin
  Fsql.Assign(Value);
  CommandText := Fsql.Text;
end;

解决方法

我不知道Delphi 2007,但是我也用Delphi 7和Oracle 8做了同样的事情.

这是我做的事情

>根据查询设置TAdoDataSet.CursorLocation:

> clUseClient如果查询获取GUI和查询的记录是相对“简单”的 – 没有分组或总和
> clUseServer如果查询有某种聚合(sum,grouping,counting)

>根据查询设置TAdoDataSet.CursorType:

> ctForward仅适用于不需要滚动浏览数据集的报表 – 仅适用于clUseServer
> ctStatic for GUI.这只是使用clUseClient的模式

>根据查询设置TAdoDataSet.LockType:

> ltReadOnly只针对不用于编辑的每个数据集(网格,报告)
>当更改后立即将数据发布到数据库时(例如用户编辑表单上的数据)
>当您更改大量记录时,ltBatchOptimistic.这是为了获取记录数量的情况,然后对它们进行一些处理,然后批量发送更新到数据库.这最好结合clUseClient和ctStatic.

>根据我的经验,Oracle的OLEDB提供商比Oracle OleDb提供者更好.你应该测试一下.编辑:检查Fabricio关于可能的blob问题的评论.>用TAdoDataSet替换TAdoQUery. TAdoQuery是为将应用从BDE转换为ADO而创建的,但是Borland / Codegear的推荐是使用TAdoDataSet>重新检查Oracle连接字符串以确保您没有网络延迟.连接到Oracle需要多长时间? TnsPing多长时间?

猜你在找的Delphi相关文章