【发布时间】:2012-08-21 17:51:07
【问题描述】:
我有一个大型 Perl 应用程序,我需要让它更快;基于它花费大部分运行时间与数据库通信,我想知道我可以运行多少编写良好的 SQL 语句并达到性能目标。为此,我编写了一个非常简单的处理程序,它执行 SELECT 和 INSERT,当我对 300 个并发请求(总共 10,000 个)进行基准测试时,结果很差(平均 1900 毫秒)。
客户端给我们的性能目标是基于他们使用的另一个用 PHP 编写的应用程序,所以我编写了一个快速的 PHP 脚本,它在功能上与我的简单 mod_perl 测试处理程序相同,平均时间为 400 毫秒!
PHP代码是:
$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";
Perl 代码是:
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;
}
mod_perl 有一个 startup.pl 脚本,在 apache 配置中使用 PerlRequire 调用,它加载所有“使用”的模块。如果一切正常,而且我没有理由认为它不是,那么每个请求都应该只运行“子处理程序”中的行——这意味着 Perl 和 PHP 应该做几乎相同的事情。
服务器详细信息:- 硬件节点是 Quad Core Xeon L5630 @ 2.13GHz with 24Gb RAM,Apache 虚拟机的操作系统是 Gentoo,Oracle 的操作系统是 Centos 5。
版本:操作系统均在过去 2 周内更新,Apache 版本 2.2.22,mod_perl 版本 2.0.4,DBI 版本 1.622,DBD::Oracle 版本 1.50,Oracle 即时客户端版本 10.2.0.3,Oracle 数据库 10g 快捷版发布10.2.0.1.0,PHP 5.3 版
Apache MPM 配置为 ServerLimit 2000、MaxClients 2000 和 MaxRequestsPerChild 300
我检查的事情:在测试期间,唯一的负载来自测试应用程序/oracle,没有一个虚拟机达到其任何 bean 计数器限制,例如内存,Oracle 始终显示每个 Apache 子节点 1 个会话,插入每次运行后完成。
所以,我的问题是;我可以让 mod_perl 版本更快吗?如果可以,如何?
【问题讨论】:
-
您应该首先比较相同的东西,因为您的 SELECT 和 INSERT 查询在 PHP 和您的 Perl 脚本之间并不相同:PHP SELECT 上的
WHERE id =1并且您正在使用 place- Perl INSERT 上的持有人(已知占位符会影响性能 - 更好或更差)。 -
没有占位符重复测试(缺少的 WHERE 是来自不同版本的剪切和粘贴)。 Perl 的新结果平均为 1810 毫秒 - PHP 与未编辑的相同。
-
找到了解决方案。在我的 PHP 测试中,我使用了 http 而不是 https。切换到 https 与 Perl 的结果非常相似。哇!
-
@Ouki 是对的,为什么只为 PHP 选择 "WHERE id = 1" 而为 Perl 选择所有内容?
标签: php performance perl oracle mod-perl2