【发布时间】:2016-05-07 19:48:36
【问题描述】:
已解决: 在第二次测试中引用值似乎是问题所在。 而不是做 'VALUES ($id, $t1....)' 我需要做 'VALUES ("$id", "$t1".....),在第二个测试中这确实是抛出错误。我看不到,只有在手动打印后才能看到。
嘿,我最近一直在使用 bindParam,发现我的页面加载时间显着增加。
所以我花了几个小时来诊断问题,似乎 bindParam 使用 A LOT 比旧时尚方式(直接在查询中使用参数)更多的处理时间
为了确保结果有效,我做了两次测试。
这是我的测试:
for ($j = 0; $j < 2; $j++) {
unset($t);
$dbh = new PDO('mysql:host=localhost;port=3306', 'root', 'root');
$dbh->query('USE Web_Amicrom_HQ');
$t['start'] = microtime(true);
for ($i = 0; $i < 50; $i++) {
$id = rand(1000000, 9999999);
$t1 = string_random(240);
$t2 = string_random(240);
$t3 = string_random(1000);
$ins = $dbh->prepare('INSERT INTO `test` (id, t1, dt, t2, t3) VALUES(:1, :2, now(), :3, :4)');
$ins->bindParam(':1', $id, PDO::PARAM_INT);
$ins->bindParam(':2', $t1, PDO::PARAM_STR);
$ins->bindParam(':3', $t2, PDO::PARAM_STR);
$ins->bindParam(':4', $t3, PDO::PARAM_STR);
$ins->execute();
}
$t['loop_fact'] = microtime(true);
echo "---- with bindParam ----\n";
$str_result_bench = mini_bench_to($t);
echo $str_result_bench; // string return
echo "\n\n";
}
for ($j = 0; $j < 2; $j++) {
unset($t);
$dbh = new PDO('mysql:host=localhost;port=3306', 'root', 'root');
$dbh->query('USE Web_Amicrom_HQ');
$t['start'] = microtime(true);
for ($i = 0; $i < 50; $i++) {
$id = rand(1000000, 9999999);
$t1 = string_random(240);
$t2 = string_random(240);
$t3 = string_random(1000);
$ins = $dbh->prepare("INSERT INTO `test` (id, t1, dt, t2, t3) VALUES($id, $t1, now(), $t2, $t3)");
$ins->execute();
}
$t['loop_fact'] = microtime(true);
echo "---- with parameter in query ----\n";
$str_result_bench = mini_bench_to($t);
echo $str_result_bench; // string return
echo "\n\n";
}
结果:
---- with bindParam ----
total time : 3136.148ms
---- with bindParam ----
total time : 2645.822ms
---- with parameter in query ----
total time : 41.693ms
---- with parameter in query ----
total time : 52.9752ms
我尝试过的事情。
将引号从双引号更改为单引号 - 没有区别
没有参数类型的bindParam(例如PDO::PARAM_INT) - 没有区别
更改了所有参数名称(例如 :1 到 :id 等) - 没有区别
这是一个很大的性能差异,尤其是对于几个查询。
【问题讨论】:
-
您是否将其与使用
execute()与数组进行比较? -
也许你可以包括所有未知的功能,这样我们就可以看到我们是否得到相同的结果
-
第二个 for 循环中的 SQL 不起作用!
-
这是一个快速编写的基准测试的典型示例,它实际上并没有测试它的设计目的。
-
您正在循环内准备查询。这可以在循环之外完成,因为它只需要完成一次