我正在制作一些返回计数和分组结果的 JSON 端点。对于此端点,我使用 PDO 和命名占位符。当使用命名占位符时,PHP 响应最多需要 6 秒的时间execute
阶段。当执行相同的查询并将值直接放入查询中时,响应几乎是即时的。
我正在更新仍使用 mysql_query() 的旧代码来使用 PDO 语句。
<?php
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
$conn = new PDO('mysql:host=localhost;dbname=nameOfDB', 'username', 'password');
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->exec("set names utf8");
$query_slow = "SELECT t.meta as meta, count(*) as cnt
FROM field, repo, t, uplink, link
WHERE (
repo.rp1 = field.id OR
repo.rp2 = field.id OR
repo.rp3 = field.id OR
repo.rp4 = field.id)
AND repo.combination = t.meta
AND t.doc_id = uplink.doc_id
AND uplink.written = 1
AND uplink.link_id = link.id
AND field.id = :field
AND t.earliest > :min
AND t.latest < :max
GROUP BY t.meta
ORDER BY cnt desc";
if($parameters){
$stmt = $conn->prepare($query_slow);
$stmt->execute($parameters);
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($data, JSON_UNESCAPED_UNICODE );
}
如果我做一个var_dump($parameters)
我得到以下返回:
$parameters = array(3) {
[":field"]=>
int(5)
[":min"]=>
int(-1000)
[":max"]=>
int(600)
}
这是快速查询:
$query_fast = "SELECT t.meta as meta, count(*) as cnt
FROM field, repo, t, uplink, link
WHERE (
repo.rp1 = field.id OR
repo.rp2 = field.id OR
repo.rp3 = field.id OR
repo.rp4 = field.id)
AND repo.combination = t.meta
AND t.doc_id = uplink.doc_id
AND uplink.written = 1
AND uplink.link_id = link.id
AND field.id=5
and t.earliest > -1000
and t.latest <600
GROUP BY t.meta
ORDER BY cnt desc";
if(1==1){
// I ditched the $parameters, so my execute is empty.
$stmt = $conn->prepare($query_slow);
$stmt->execute();
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($data, JSON_UNESCAPED_UNICODE );
}
Slow_query 最多可能需要 6 秒才能运行。如果我使用填充的值和空的值运行相同的查询execute()
我几乎立刻就得到了回应。我对 PDO 做错了什么?
当给一个数组时execute()
我的页面响应速度很慢。当使用没有参数的查询时。响应是即时的。
我的计时代码按照@RiggsFolly的要求:
所以我在那里运行了计时代码:
if($parameters){
$time_prepare = microtime(true);
$stmt = $conn->prepare($querygraph);
$time_pre_exec = microtime(true);
$stmt->execute(($parameters));
//$stmt->execute();
$time_post_exec = microtime(true);
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
$time_post_fetch = microtime(true);
echo json_encode($data, JSON_UNESCAPED_UNICODE );
}
这是使用参数 5、-800 和 800(与之前使用的相同)。我的计时代码显示:
start: 1563972660.9188 (First line of the script)
prepare: 1563972660.9197 ==$time_prepare
pre execution: 1563972660.9201 ==$time_pre_exec
post execution: 1563972669.0058 ==$time_post_exec ==> 9 seconds!
post fetch: 1563972669.0058
当在没有占位符的查询上使用相同的参数时,我使用相同的查询和空的execute()。我将占位符替换为我在准备好的语句中使用的相同值。时间看起来像:
prepare: 1563973120.2965
pre execution: 1563973120.2969 //before execution()
post execution: 1563973120.312 //after executeion()
post fetch: 1563973120.3121