I have a large Perl app that I need to make faster; on the basis that it spends most of its running time talking to the DB I wanted to know how many well written SQL statements I could run and meet the performance targets. To do this I wrote a very simple handler that does a SELECT and an INSERT, when I benchmarked it on 300 concurrent requests (10,000 in total) the results were quite poor (1900ms average).
The performance target we've been given by the client is based on another app they use written in PHP, so I wrote a quick PHP script that does functionally the same thing as my simple mod_perl test handler and it gave a 400ms average!
The PHP code is:
$cs = "//oracle.ourdomain.com:1521/XE";
$oc = oci_pconnect("hr","password",$cs);
if(!$oc) { print oci_error(); }
$stid = oci_parse($oc, 'SELECT id FROM zz_system_options WHERE id = 1');
oci_execute($stid);
$stmt = oci_parse($oc, "INSERT INTO zz_system_options (id,option_name) VALUES (zz_system_optionsids.nextval,'load testing')");
oci_execute($stmt);
echo "hello world";
The Perl code is:
use strict;
use Apache2::RequestRec ();
use Apache2::RequestIO ();
use Apache2::Const -compile => qw(:common);
use DBI;
our $dbh;
sub handler
{
my $r = shift;
# Connect to DB
$dbh = DBI->connect( "DBI:Oracle:host=oracle.ourdoamin.com;port=1521;sid=XE", "hr", "password" ) unless $dbh;
my $dbi_query_object = $dbh->prepare("SELECT id FROM zz_system_options");
$dbi_query_object->execute();
$dbi_query_object =
$dbh->prepare("INSERT INTO zz_system_options (id,option_name) VALUES (zz_system_optionsids.nextval,?)");
$dbi_query_object->execute("load testing");
# Print out some info about this...
$r->content_type('text/plain');
$r->print("Errors: $err\n");
return Apache2::Const::OK;
}
The mod_perl has a startup.pl script called with a PerlRequire in the apache config that loads all the 'use'd modules. If all is working correctly, and I've no reason to think it isn't, then each request should only run the lines in 'sub handler' - meaning the Perl and PHP should be doing pretty much the same thing.
Server details:- The hardware node is a Quad Core Xeon L5630 @ 2.13GHz with 24Gb RAM, the OS for the Apache virtual machine is Gentoo, the OS for Oracle is Centos 5,.
Versions: OSes both updated within last 2 weeks, Apache version 2.2.22, mod_perl version 2.0.4, DBI Version 1.622, DBD::Oracle version 1.50, Oracle instant client version 10.2.0.3, Oracle Database 10g Express Edition Release 10.2.0.1.0, PHP version 5.3
Apache MPM config is ServerLimit 2000, MaxClients 2000 and MaxRequestsPerChild 300
Things I checked: during the testing the only load was from the test app/oracle, neither virtual machine hit any of its bean counter limits, e.g., memory, Oracle showed 1 session per Apache child at all times, inserts had been done after each run.
So, my question is; Can I make the mod_perl version faster and if so how?