473,406 Members | 2,620 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

Oracle DB access - having problems with speed?

I think I'm doing something wrong. I'm able to connect to Oracle just
fine, execute queries and all, but I'm having serious problems with
the speed :(

For example, the following PHP-script on my machine executes about 6
seconds:

<?
$db_conn = ocilogon("my_username", "my_password", "my_database");
$loop_count = 1000;
$query = "insert into oratest (id, text) values (:id, :data)";
$parsed = ociparse($db_conn, $query);
ocibindbyname($parsed, ":id", $x, 4);
ocibindbyname($parsed, ":data", $now, 14);
for ($x = 1; $x <= $loop_count; $x++) {
$now = date("YmdHis");
ociexecute($parsed, OCI_DEFAULT);
ocicommit($db_conn);
}
?>

However, if I have the following PL/SQL -stored procedure, it executes
in less than a second:

procedure testing is
l_loop_count number(10);
begin
l_loop_count := 1000;
for x in 1..l_loop_count loop
execute immediate 'insert into oratest (id, text) values ('||x||',
'''||toolkit.get_timestamp||''')';
commit;
end loop;
end;

Please note, that the only reason I used "execute immediate" instead
of just using a normal insert, was that execute immediate is a tiny
bit slower :)

The underlying table is defined as "CREATE TABLE ORATEST (id
NUMBER(10) NOT NULL, text VARCHAR2(14) NOT NULL);", I'm using PHP
4.3.1 (Yeah, somewhat outdated at the moment) on Apache 1.3.22 (the
one that came with my Oracle) running on Windows XP (SP2), OCI8 is
revision 1.183 ... in case any of this has any meaning.

Has anyone got experience on this field? Is there something I'm
overlooking? Any hints are appreciated. The reason I'm attempting to
do this with PHP is that I wish to have Object-capabilities in the
next version of my software, that has previously been built using just
PL/SQL.

--
Markku Uttula

Jul 17 '05 #1
11 3281

"Markku Uttula" <ma***********@disconova.com> wrote in message
news:Gg****************@reader1.news.jippii.net...
I think I'm doing something wrong. I'm able to connect to Oracle just fine,
execute queries and all, but I'm having serious problems with the speed :(

For example, the following PHP-script on my machine executes about 6
seconds:

<?
$db_conn = ocilogon("my_username", "my_password", "my_database");
$loop_count = 1000;
$query = "insert into oratest (id, text) values (:id, :data)";
$parsed = ociparse($db_conn, $query);
ocibindbyname($parsed, ":id", $x, 4);
ocibindbyname($parsed, ":data", $now, 14);
for ($x = 1; $x <= $loop_count; $x++) {
$now = date("YmdHis");
ociexecute($parsed, OCI_DEFAULT);
ocicommit($db_conn);
}
?>

I do not know oracle with php but, do you need the ocicommit($db_conn);
every single time in your loop.
To me it lloks like your connecting with the database 1000 times. Can't you
just connect once.
I may be way off base here, but it's worth saying.

Brent Palmer.


However, if I have the following PL/SQL -stored procedure, it executes in
less than a second:

procedure testing is
l_loop_count number(10);
begin
l_loop_count := 1000;
for x in 1..l_loop_count loop
execute immediate 'insert into oratest (id, text) values ('||x||',
'''||toolkit.get_timestamp||''')';
commit;
end loop;
end;

Please note, that the only reason I used "execute immediate" instead of
just using a normal insert, was that execute immediate is a tiny bit
slower :)

The underlying table is defined as "CREATE TABLE ORATEST (id NUMBER(10)
NOT NULL, text VARCHAR2(14) NOT NULL);", I'm using PHP 4.3.1 (Yeah,
somewhat outdated at the moment) on Apache 1.3.22 (the one that came with
my Oracle) running on Windows XP (SP2), OCI8 is revision 1.183 ... in case
any of this has any meaning.

Has anyone got experience on this field? Is there something I'm
overlooking? Any hints are appreciated. The reason I'm attempting to do
this with PHP is that I wish to have Object-capabilities in the next
version of my software, that has previously been built using just PL/SQL.

--
Markku Uttula

Jul 17 '05 #2
Brent Palmer wrote:
<?
$db_conn = ocilogon("my_username", "my_password", "my_database");
$loop_count = 1000;
$query = "insert into oratest (id, text) values (:id, :data)";
$parsed = ociparse($db_conn, $query);
ocibindbyname($parsed, ":id", $x, 4);
ocibindbyname($parsed, ":data", $now, 14);
for ($x = 1; $x <= $loop_count; $x++) {
$now = date("YmdHis");
ociexecute($parsed, OCI_DEFAULT);
ocicommit($db_conn);
}
I do not know oracle with php but, do you need the
ocicommit($db_conn); every single time in your loop.


No. It's just there to make the DB-server actually "do something"
while in the loop (because I don't want to test the speed of the
memorypool). I've done it similarly in the PL/SQL-code. It's true that
I'd neve do something like this in production environment - the commit
would be only after all the inserts are made - but as said, that
wouldn't be testing the speed of accessing the database itself.

It is true, that when I move the ocicommit outside the loop, the speed
goes up by (nearly) a factor of five. Interestingly, when I move the
commit outside of the loop in PL/SQL-code, the speed slows down by
nearly the same amount. Very interesting results :-p
To me it lloks like your connecting with the database 1000 times.
Can't you just connect once.


Nope, the connection is established on the first line of script.
Committing changes does not (or at least, it should not) break the
connection.

--
Markku Uttula

Jul 17 '05 #3
Brent Palmer wrote:

"Markku Uttula" <ma***********@disconova.com> wrote in message
news:Gg****************@reader1.news.jippii.net...
I think I'm doing something wrong. I'm able to connect to Oracle just
fine, execute queries and all, but I'm having serious problems with the
speed :(

Yup, sounds like Oracle ;)
For example, the following PHP-script on my machine executes about 6
seconds:

<?
$db_conn = ocilogon("my_username", "my_password", "my_database");
$loop_count = 1000;
$query = "insert into oratest (id, text) values (:id, :data)";
$parsed = ociparse($db_conn, $query);
ocibindbyname($parsed, ":id", $x, 4);
ocibindbyname($parsed, ":data", $now, 14);
for ($x = 1; $x <= $loop_count; $x++) {
$now = date("YmdHis");
ociexecute($parsed, OCI_DEFAULT);
ocicommit($db_conn);
}
?>


To me it lloks like your connecting with the database 1000 times.


No, but he's sending 2000 requests through the same connection. To run the
PL/SQL requires only 1 request to the DBMS, the iteration is carried out
within the DBMS. This ultimately is the issue - it doesn't matter what DBMS
is used. Unless you're really doing something dumb though, it's hardly a
representative test - a real application still needs the data sent from the
front-end to the back-end, so the PL/SQL vs PHP performance issue is void.

Even if the 'real' application is to generate a table containing a 1000 rows
of int, time there are much better algorithmic solutions. e.g. IIRC, Oracle
allows an INSERT statement to add multiple rows.

C.

Jul 17 '05 #4
Markku Uttula wrote:
I think I'm doing something wrong. I'm able to connect to Oracle just
fine, execute queries and all, but I'm having serious problems with the
speed :(

For example, the following PHP-script on my machine executes about 6
seconds:

<?
$db_conn = ocilogon("my_username", "my_password", "my_database");
$loop_count = 1000;
$query = "insert into oratest (id, text) values (:id, :data)";
$parsed = ociparse($db_conn, $query);
ocibindbyname($parsed, ":id", $x, 4);
ocibindbyname($parsed, ":data", $now, 14);
for ($x = 1; $x <= $loop_count; $x++) {
$now = date("YmdHis");
ociexecute($parsed, OCI_DEFAULT);
ocicommit($db_conn);
}
?>

However, if I have the following PL/SQL -stored procedure, it executes
in less than a second:

procedure testing is
l_loop_count number(10);
begin
l_loop_count := 1000;
for x in 1..l_loop_count loop
execute immediate 'insert into oratest (id, text) values ('||x||',
'''||toolkit.get_timestamp||''')';
commit;
end loop;
end;

Please note, that the only reason I used "execute immediate" instead of
just using a normal insert, was that execute immediate is a tiny bit
slower :)

The underlying table is defined as "CREATE TABLE ORATEST (id NUMBER(10)
NOT NULL, text VARCHAR2(14) NOT NULL);", I'm using PHP 4.3.1 (Yeah,
somewhat outdated at the moment) on Apache 1.3.22 (the one that came
with my Oracle) running on Windows XP (SP2), OCI8 is revision 1.183 ...
in case any of this has any meaning.

Has anyone got experience on this field? Is there something I'm
overlooking? Any hints are appreciated. The reason I'm attempting to do
this with PHP is that I wish to have Object-capabilities in the next
version of my software, that has previously been built using just PL/SQL.

Upgrade to Apache 2 and PHP 5. In PHP 5, you use oci_* functions rather
than oci* functions. These will be faster.

Jamie
Jul 17 '05 #5
James Pittman wrote:
Upgrade to Apache 2 and PHP 5. In PHP 5, you use oci_* functions
rather than oci* functions. These will be faster.


I just had to really test this, and nope - it doesn't seem to be the
case. The functions have no notable difference in speed (and I wonder
how - in theory - they even could have).

--
Markku Uttula

Jul 17 '05 #6
Colin McKinnon wrote:
I think I'm doing something wrong. I'm able to connect to Oracle
just fine, execute queries and all, but I'm having serious
problems
with the speed :(
Yup, sounds like Oracle ;)
Do you mean Oracle in general, or Oracle while used through PHP?
To me it lloks like your connecting with the database 1000 times.


No, but he's sending 2000 requests through the same connection. To
run the PL/SQL requires only 1 request to the DBMS, the iteration is
carried out within the DBMS. This ultimately is the issue - it
doesn't matter what DBMS is used.


<HOMER>D'oh</HOMER> ... how the heck didn't I think of that... I was
in the mindset that PL/SQL stored procedures were being executed in
Apache's mod_plsql, but now that I really think of it, why would it...
Makes one wonder how stupid things one can do even with 5 years of
experience developing software using Oracle :-p
Unless you're really doing
something dumb though, it's hardly a representative test - a real
application still needs the data sent from the front-end to the
back-end, so the PL/SQL vs PHP performance issue is void.


Yep. I was actually doing this with such vast amounts of data to get
something I could really measure the time with. On a real environment,
the amounts of data stored are nowhere close to this per transaction,
so you're 100% correct that this example gives no real pointers to
what the actual performance would be.

--
Markku Uttula

Jul 17 '05 #7
On Thu, 17 Mar 2005 08:06:02 -0500, James Pittman <jp*******@yahoo.com> wrote:
Markku Uttula wrote:

Upgrade to Apache 2 and PHP 5. In PHP 5, you use oci_* functions rather
than oci* functions. These will be faster.


No, they won't. It's the same extension. The functions have just been renamed.
And the oci* functions are still there are aliases.

You're probably comparing with the ora_ functions, which are based on the
long-dead OCI7.

--
Andy Hassall / <an**@andyh.co.uk> / <http://www.andyh.co.uk>
<http://www.andyhsoftware.co.uk/space> Space: disk usage analysis tool
Jul 17 '05 #8
Andy Hassall wrote:
On Thu, 17 Mar 2005 08:06:02 -0500, James Pittman <jp*******@yahoo.com> wrote:

Markku Uttula wrote:

Upgrade to Apache 2 and PHP 5. In PHP 5, you use oci_* functions rather
than oci* functions. These will be faster.

No, they won't. It's the same extension. The functions have just been renamed.
And the oci* functions are still there are aliases.

You're probably comparing with the ora_ functions, which are based on the
long-dead OCI7.

Yeah I guess I am. I do remember seeing a speed increase from ora_* to
oci*.

Jamie
Jul 17 '05 #9
Markku Uttula wrote:
I think I'm doing something wrong. I'm able to connect to Oracle just
fine, execute queries and all, but I'm having serious problems with the
speed :(

For example, the following PHP-script on my machine executes about 6
seconds:

<?
$db_conn = ocilogon("my_username", "my_password", "my_database");
$loop_count = 1000;
$query = "insert into oratest (id, text) values (:id, :data)";
$parsed = ociparse($db_conn, $query);
ocibindbyname($parsed, ":id", $x, 4);
ocibindbyname($parsed, ":data", $now, 14);
for ($x = 1; $x <= $loop_count; $x++) {
$now = date("YmdHis");
ociexecute($parsed, OCI_DEFAULT);
ocicommit($db_conn);
}
?>

However, if I have the following PL/SQL -stored procedure, it executes
in less than a second:

procedure testing is
l_loop_count number(10);
begin
l_loop_count := 1000;
for x in 1..l_loop_count loop
execute immediate 'insert into oratest (id, text) values ('||x||',
'''||toolkit.get_timestamp||''')';
commit;
end loop;
end;

Please note, that the only reason I used "execute immediate" instead of
just using a normal insert, was that execute immediate is a tiny bit
slower :)

The underlying table is defined as "CREATE TABLE ORATEST (id NUMBER(10)
NOT NULL, text VARCHAR2(14) NOT NULL);", I'm using PHP 4.3.1 (Yeah,
somewhat outdated at the moment) on Apache 1.3.22 (the one that came
with my Oracle) running on Windows XP (SP2), OCI8 is revision 1.183 ...
in case any of this has any meaning.

Has anyone got experience on this field? Is there something I'm
overlooking? Any hints are appreciated. The reason I'm attempting to do
this with PHP is that I wish to have Object-capabilities in the next
version of my software, that has previously been built using just PL/SQL.

Somewhere buried in the thread is a thought regarding PHP 4 etc.

If you have access to PHP 5 then go for it, Ignoring Oracle issues for
the moment, PHP 5 gives you try catch exception handling, makes life so
much easier <g>
Jul 17 '05 #10
NSpam wrote:
Markku Uttula wrote:
I think I'm doing something wrong. I'm able to connect to Oracle just
fine, execute queries and all, but I'm having serious problems with
the speed :(

For example, the following PHP-script on my machine executes about 6
seconds:

<?
$db_conn = ocilogon("my_username", "my_password", "my_database");
$loop_count = 1000;
$query = "insert into oratest (id, text) values (:id, :data)";
$parsed = ociparse($db_conn, $query);
ocibindbyname($parsed, ":id", $x, 4);
ocibindbyname($parsed, ":data", $now, 14);
for ($x = 1; $x <= $loop_count; $x++) {
$now = date("YmdHis");
ociexecute($parsed, OCI_DEFAULT);
ocicommit($db_conn);
}
?>

However, if I have the following PL/SQL -stored procedure, it executes
in less than a second:

procedure testing is
l_loop_count number(10);
begin
l_loop_count := 1000;
for x in 1..l_loop_count loop
execute immediate 'insert into oratest (id, text) values ('||x||',
'''||toolkit.get_timestamp||''')';
commit;
end loop;
end;

Please note, that the only reason I used "execute immediate" instead
of just using a normal insert, was that execute immediate is a tiny
bit slower :)

The underlying table is defined as "CREATE TABLE ORATEST (id
NUMBER(10) NOT NULL, text VARCHAR2(14) NOT NULL);", I'm using PHP
4.3.1 (Yeah, somewhat outdated at the moment) on Apache 1.3.22 (the
one that came with my Oracle) running on Windows XP (SP2), OCI8 is
revision 1.183 ... in case any of this has any meaning.

Has anyone got experience on this field? Is there something I'm
overlooking? Any hints are appreciated. The reason I'm attempting to
do this with PHP is that I wish to have Object-capabilities in the
next version of my software, that has previously been built using just
PL/SQL.

Somewhere buried in the thread is a thought regarding PHP 4 etc.

If you have access to PHP 5 then go for it, Ignoring Oracle issues for
the moment, PHP 5 gives you try catch exception handling, makes life so
much easier <g>

Whoops also forgot PHP 5 object behaviour is far better
Jul 17 '05 #11
On Thu, 17 Mar 2005 11:40:01 +0200, "Markku Uttula"
<ma***********@disconova.com> wrote:
I think I'm doing something wrong. I'm able to connect to Oracle just
fine, execute queries and all, but I'm having serious problems with
the speed :(

For example, the following PHP-script on my machine executes about 6
seconds:

$loop_count = 1000;
$query = "insert into oratest (id, text) values (:id, :data)";
$parsed = ociparse($db_conn, $query);
ocibindbyname($parsed, ":id", $x, 4);
ocibindbyname($parsed, ":data", $now, 14);
for ($x = 1; $x <= $loop_count; $x++) {
$now = date("YmdHis");
ociexecute($parsed, OCI_DEFAULT);
ocicommit($db_conn);
}

However, if I have the following PL/SQL -stored procedure, it executes
in less than a second:

procedure testing is
l_loop_count number(10);
begin
l_loop_count := 1000;
for x in 1..l_loop_count loop
execute immediate 'insert into oratest (id, text) values ('||x||',
'''||toolkit.get_timestamp||''')';
commit;
end loop;
end;

Please note, that the only reason I used "execute immediate" instead
of just using a normal insert, was that execute immediate is a tiny
bit slower :)


As others have said, the main reason here is likely to be database roundtrips;
the first one does at least 2001 round trips (1x prepare, 1000x bind+execute,
1000x commit), the second does 2 (1x prepare, 1x bind+execute).

I also seem to recall that PL/SQL has an optimisation with regards to commits
in loops; it may not actually do the commit until the end.

Consider that a commit partly means "do not return control to the client until
it is guaranteed that the changes I just made have been written to the redo
logs". If you're executing a PL/SQL block, control doesn't return to the client
until the whole block is finished. So PL/SQL can defer the physical effects of
the commit until the block completes.

I think this is the page that I'm remembering that explains some of this:
http://www.oracledba.co.uk/tips/lgwr_dilemma.htm

Commits are relatively expensive, so this may also contribute to the time
differences.

Note also that the PL/SQL version not only uses execute immediate,
guaranteeing soft parses for each execution, but you've also embedded literals
in the SQL you're executing, resulting in a potential hard parse for every
iteration, unless (a) you've done this loop before and they're still in the
cache, or (b) you've got cursor_sharing set to 'similar' or 'force' so it
rewrites SQL with embedded literals using bind variables.

Unless you're deliberately trying to make performance worse, if you do have to
resort to using execute immediate then you can still use bind variables, e.g.:

execute immediate 'insert into oratest (id, text) values (:x, :y)'
using x, toolkit.get_timestamp;

No doubt this is old news to you but I just didn't like seeing embedded
literals in SQL go unchallenged in case someone else saw it and thought it was
a good idea.
Drifting further off-thread, after a while I got fed up with the OCI8
extension in PHP in its raw form; it's a little too close to the OCI interface,
which whilst this is a great thing from performance point of view, it's a bit
verbose. After checking out various database layers I settled on ADOdb and I'm
very happy with that - it abstracts out the parse/bind/execute stuff just
enough for usability, but it's a thin enough layer that it doesn't cost much in
the way of speed.

--
Andy Hassall / <an**@andyh.co.uk> / <http://www.andyh.co.uk>
<http://www.andyhsoftware.co.uk/space> Space: disk usage analysis tool
Jul 17 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Terence | last post by:
These comparrison articles are always fun :) http://otn.oracle.com/pub/articles/hull_asp.html
38
by: Mike | last post by:
No flame wars, please! We're planning a move from a non-relational system to a relational system. Our choices have been narrowed to Oracle and DB2. Since we're moving from non-relational to...
13
by: BigDaDDY | last post by:
Um yeah....In case you haven't figured it out, Microsoft sucks. I'm going to be kicked back in my chair eating popcorn and watching football 10 years from now, while all you clowns are scrambling...
9
by: mcbill20 | last post by:
Hello all. I just installed Oracle 10g developer tools on a machine running XP Pro and Office XP. Before this I had just the Oracle 9 client installed. I the previous configuration, I was able to...
1
by: s-dogg | last post by:
If anyone has seen this before, please help. I work at a company that has an Access application front end attached to tables in an Oracle 10g backend. In order to run our application this way,...
9
by: AnandaSim | last post by:
Hi All, I've had Access 97, 2000 connections to the corporate Oracle database for a few years now - but seldom use it. When I did use it years ago, performance was not fast but the features were...
2
by: egoldthwait | last post by:
I need to convert a 17mb access 2000 db to Oracle and house it in a Citrix farm. The issue: we have never converted an Access Db to Oracle but can probably use Oracle's Workbench to assist with...
37
by: jasmith | last post by:
How will Access fair in a year? Two years? .... The new version of Access seems to service non programmers as a wizard interface to quickly create databases via a fancy wizard. Furthermore, why...
5
by: jonceramic | last post by:
Hi All, I started developing in Access, and people took notice and so we're starting to migrate into our corporate's bigger Oracle system. I'll still be using my developed Access front ends,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.