Performance when launched from a windows service

jeckels

Member
Some background

My environment is Delphi 7, DOA 3.4.6.4 (preparing update to 4.1). Oracle access is non-visual. I am only using TOracleSession for connections (one / thread in my application), TOracleQuery (for update/delete/inserts), TOracleDataset (for selects).

I have a windows scheduler service (written in Delphi 7), which is pretty lightweight (uses only TOracleSession & TOracleDataset). It checks a table in the database for something to do, and then if it finds something, it launches (CreateProcess) an executeable that does the work. The service is running as the local system account.

The executable (also written in Delphi 7), creates a predefined number of threads. Each thread has its own TOracleSession.

Ok, so here's my findings.

When I run the executable manually, as myself (outside of the service), the process takes 30 seconds.
When I let the scheduler service run that very same executable, it takes 110 seconds. Almost 4x slower. I've tried changing the service to log on as myself .. same poor result.

Nothing else is running, nothing that I can identify to help me explain this.

So, what I did was "stub out" the actual database calls in the executable, and replaced them with bogus code (effectively bypassing DOA aside from some rudimentary connection and 2-3 queries, but no queries running on each thread).

Under that, I get identical results running the console app vs letting the service run the console app. This leads me to believe the issue resides inside the DOA code.

I am not versed in how to debug this kind of thing when its running as a service.

I can reproduce this on every windows OS. I have noticed that the more threads there are, the worse it gets. On a 32 core system, the kernel time is upwards of 90-95% of CPU time(from what I understand, that means contention, and alots of it).

At a client site with 32 cores, the difference is crazy. Running as a service, takes 47 hours. Running that same thing from the commandline, 90 minutes.

I've checked my code (outside of the DOA library) over and over. Verifying areas of contention (critical sections, etc); and all profiles correctly.

I have noticed that the CPU kernel time is almost nothing when run as a console app, but almost 50% kernel time when that same app is launched under a service.

Has anyone seen this, or have recommendations that would cause this kind of performance hit? Does something special need to be done to setup the OCI for the Oracle client I have installed? Has someone heard of a patch (perhaps even to Delphi) that eliminates this service problem?

Notes - The same applicationc code supports Oracle & SQL Server. Our SQL Server libraries (ADO) do not have this issue.
Using DOA 3.4.6.4 runs about 35% faster than v4 from the console. Which was unexpected.

Thanks, in advance, for any feedback/direction on this.

 
Last edited:
I should add the specifics for

TOracleSession
.ThreadSafe := True;
.AutoCommit := False;

TOracleDataset
.Session := MySession;
.ReadOnly := True;
.Unidirectional := True;
.ReadBuffer := 1000;

TOracleQuery
.Session := MySession;

 
Can you use a DBA tool to check if the elapsed time for the queries running as a service is longer than when executed interactively?

If the database performance is different, then this may be an environment issue and you will need to look into the query execution statistics to find a clue.

If the database performance is the same, then time is most likely lost in the Oracle Client Library and we would have to look into that.
 
Verified the DB performance for the queries is unchanged for all tests.

What are the optimal settings for a multi-threaded application where each thread owns their own session, and all thread queries are against that thread session, and all thread queries are expected to run (and wait until finished) before returning to the caller?

If I have each thread with their own session, should I set the TOracleSession.ThreadSafe to True? If so, and I want my queries to run linearly on that session, should those TOracleQuery.Threaded be set to true or false?

 
I will add that our latest test is a 32bit OS running this does not appear to have this problem. So, it looks like something with 32bit oracle client on a 64bit system (WOW).
 
Back
Top