表现 – BDE与ADO在德尔福
请注意下面的编辑更多信息,以及可能的解决方案
我们最近修改了一个大型Delphi应用程序来使用ADO连接和查询而不是BDE连接和查询.由于这种变化,表现已经变得可怕了. 我已经分析了应用程序,并且瓶颈似乎在实际调用TADOQuery.Open.换句话说,从代码角度来看,除了重组应用程序以减少实际使用的数据之外,还没有太多的工作来改进这一点. 有没有人有关于如何提高ADO连接的Delphi应用程序的性能的建议?我已经尝试了suggestions given here,几乎没有任何影响. 为了给出性能差异的想法,我对同样大的操作进行了基准测试: >在BDE下:11秒 我们正在客户端 – 服务器环境中使用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和查询的记录是相对“简单”的 – 没有分组或总和 >根据查询设置TAdoDataSet.CursorType: > ctForward仅适用于不需要滚动浏览数据集的报表 – 仅适用于clUseServer >根据查询设置TAdoDataSet.LockType: > ltReadOnly只针对不用于编辑的每个数据集(网格,报告) >根据我的经验,Oracle的OLEDB提供商比Oracle OleDb提供者更好.你应该测试一下.编辑:检查Fabricio关于可能的blob问题的评论.>用TAdoDataSet替换TAdoQUery. TAdoQuery是为将应用从BDE转换为ADO而创建的,但是Borland / Codegear的推荐是使用TAdoDataSet>重新检查Oracle连接字符串以确保您没有网络延迟.连接到Oracle需要多长时间? TnsPing多长时间? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |