【发布时间】:2016-12-20 19:27:25
【问题描述】:
我认为在逐一循环超过一千条记录时,我会看到使用 PDO 语句 和 PDO 查询 之间存在明显的性能差异。
我为每一个循环做了一千次,以获得平均结果,它们反映的时间几乎相同(≈0.105 秒)。为什么?我会认为准备好的语句是最快的。
这是我用于测试目的的代码:
$iter = 1000;
$idAry = range(1,1000);
$sumResultAry = array();
// [TEST1]
$func1 = function($id,array &$sumResultAry){
list($dbCon,$DB,$TP) = AClass::retrieve_database_properties_();
$sql = "
SELECT
t1.id,
t1.look_key
FROM {$DB}.{$TP}test t1
WHERE
t1.id={$id}
";
if(false!==($result=$dbCon->query($sql))){
if(false!==($row=$result->fetch(PDO::FETCH_ASSOC))){
$sumResultAry[] = $row['id'];
}
}
};
$wh = fopen('test','w');
if($wh){
for($i=0;$i<$iter;++$i){
$startTime = microtime(true);
foreach($idAry as $id){
$func1($id,$sumResultAry);
}
$endTime = number_format((microtime(true)-$startTime),4);
fwrite($wh,$endTime . "\n");
}
fclose($wh);
}
$result = 0;
$rh = fopen('test','r');
if($rh){
while(!feof($rh)){
$line = trim(fgets($rh));
if($line!==''){
$result += floatval($line);
}
}
fclose($rh);
}
echo '<pre>';
echo 'test query' . "\n\n";
echo 'time: ' . ($result/$iter) . ' seconds' . "\n\n";
echo '</pre>';
// [/TEST1]
// [TEST2]
$func2 = function($id,array &$sumResultAry){
$key = 'test';
$sqlStmt = null;
if(null===($sqlStmt=AClass::return_sqlStatement_($key))){// retrieving statement if previously stored
list($dbCon,$DB,$TP) = AClass::retrieve_database_properties_();
$sql = "
SELECT
t1.id,
t1.look_key
FROM {$DB}.{$TP}test t1
WHERE
t1.id=:id
";
if(AClass::prepare_sqlStatement_($key,$sql)){// preparing and storing statement
$sqlStmt = AClass::return_sqlStatement_($key);
}
}
if(null!==$sqlStmt){
if(false!==($sqlStmt->execute(array(':id'=>$id)))){
if(false!==($row=$sqlStmt->fetch(PDO::FETCH_ASSOC))){
$sumResultAry[] = $row['id'];
}
}
}
};
$wh = fopen('test','w');
if($wh){
for($i=0;$i<$iter;++$i){
$startTime = microtime(true);
foreach($idAry as $id){
$func2($id,$sumResultAry);
}
$endTime = number_format((microtime(true)-$startTime),4);
fwrite($wh,$endTime . "\n");
}
fclose($wh);
}
$result = 0;
$rh = fopen('test','r');
if($rh){
while(!feof($rh)){
$line = trim(fgets($rh));
if($line!==''){
$result += floatval($line);
}
}
fclose($rh);
}
echo '<pre>';
echo 'test statement' . "\n\n";
echo 'time: ' . ($result/$iter) . ' seconds' . "\n\n";
echo '</pre>';
// [/TEST2]
感谢你们中的一些人,我现在明白我需要使用更复杂的查询进行测试,才能注意到两者之间的显着性能差异。
【问题讨论】:
-
根据天空中的伟大手册。 “通过使用准备好的语句,应用程序避免了重复分析/编译/优化循环。” php.net/manual/en/pdo.prepared-statements.php 您的查询非常简单,因此分析/编译/优化周期的 1000 次迭代可以忽略不计。尝试更复杂的查询。 (添加依赖子查询等)
-
@brassxzero 哦,我明白了!因此,对于更复杂的查询,我会看到不同之处。我将进一步测试以验证这一点。我知道这些东西可能已经测试了一千次,但我只是添加了一个类来存储在我的项目中使用的准备好的语句,并且想看看我这样做是否是好的,所以我开始测试它。谢谢。
-
这里有问题吗?
-
@bassxzero 我一直将运行分析/编译/优化周期的过程称为“确定执行计划”。在 mysql(假设 mysql 或 postgres)中,这是准确的正确语言吗?
-
这完全不清楚。
标签: php pdo prepared-statement