Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 87677
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 10, 20262026-05-10T22:26:25+00:00 2026-05-10T22:26:25+00:00

Please note the Edit below for a lot more information, and a possible solution

  • 0

Please note the Edit below for a lot more information, and a possible solution

We recently modified a large Delphi application to use ADO connections and queries instead of BDE connections and queries. Since that change, performance has become terrible.

I’ve profiled the application and the bottleneck seems to be at the actual call to TADOQuery.Open. In other words, there isn’t much I can do from a code standpoint to improve this, other than restructuring the application to actually use the database less.

Does anyone have suggestions about how to improve the performance of an ADO-connected Delphi application? I’ve tried both of the suggestions given here, with virtually no impact.

To give an idea of the performance difference, I benchmarked the same large operation:

  • Under BDE: 11 seconds

  • Under ADO: 73 seconds

  • Under ADO after the changes referenced by that article: 72 seconds

We are using an Oracle back-end in a client-server environment. Local machines each maintain a separate connection to the database.

For the record, the connection string looks like this:

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=*******'; 

To answer the questions posed by zendar:

I’m using Delphi 2007 on Windows Vista and XP.

The back end is an Oracle 10g database.

As indicated by the connection string, we are using the OraOLEDB driver.

The MDAC version on my benchmark machine is 6.0.

Edit:

Under the BDE, we had a lot of code that looked like this:

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 

But we found that the call to Sql.Add is actually very expensive under ADO, because the QueryChanged event is fired every time you change the CommandText. So replacing the above with this was MUCH faster:

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 

Better yet, you can copy TADOQuery out of ADODB.pas, rename it under a new name, and rip out the QueryChanged event, which as far as I can tell, is not doing anything useful at all. Then use your new, modified version of TADOQuery, instead of the native one.

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; 
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. 2026-05-10T22:26:26+00:00Added an answer on May 10, 2026 at 10:26 pm

    I don’t know about Delphi 2007, but I did same thing with Delphi 7 and Oracle 8.

    Here are things I did:

    • Set TAdoDataSet.CursorLocation according to query:
      • clUseClient if query fetches records for GUI and query is relatively ‘simple’ – no grouping or sum
      • clUseServer if query have some sort of aggregation (sum, grouping, counting)
    • Set TAdoDataSet.CursorType according to query:
      • ctForwardOnly for reports where you don’t need scroll back through dataset – works only with clUseServer
      • ctStatic for GUI. This is only mode that works with clUseClient
    • Set TAdoDataSet.LockType according to query:
      • ltReadOnly for every dataset that is not used for editing (grids, reports)
      • ltOptimistic when records are posted to database immediately after change (e.g. user editing data on form)
      • ltBatchOptimistic when you change large number of records. This is for situations where you fetch number of records, then do some processing on them and then send updates to database in batch. This works best combined with clUseClient and ctStatic.
    • In my experience, Microsoft OLEDB provider for Oracle worked better than Oracle OleDb provider. You should test that.
      Edit: Check Fabricio’s comment about possible blob problems.
    • Replace TAdoQUery with TAdoDataSet. TAdoQuery was created for conversion of apps from BDE to ADO, but Borland/Codegear recomendation was to use TAdoDataSet
    • Recheck Oracle connection string to be sure that you do not have network latency. How long it lasts to connect to Oracle? How long is TnsPing?
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 118k
  • Answers 119k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer Have you looked at http://www.smartclient.com/smartgwt/showcase/ The controls are licensed as… May 11, 2026 at 11:40 pm
  • Editorial Team
    Editorial Team added an answer If I understand you right, Nope. Everything that comes in… May 11, 2026 at 11:40 pm
  • Editorial Team
    Editorial Team added an answer Found my error. I initialized the pointer Sprite *gobs[5]; in… May 11, 2026 at 11:40 pm

Related Questions

I've created a question about this a few days . My solution is something
Below is code which includes a variadic function and calls to the variadic function.
I'm wondering what a better design is for the intersection table for a many-to-many
I've been investigating this issue that only seems to get worse the more I

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.