![](/img/trans.png)
[英]mysqli_stmt::bind_param and mysqli_stmt::prepare
[英]MYSQL query performance very poor when using PHP mysqli_stmt::bind_param() compared to PDOStatement::bindParam()
在运行以下命令时,我遇到了与使用 PHP mysqli_stmt::bind_param()
相关的性能问题:
$sql = "select ts from scans where sessionid = ? order by id desc limit 1";
$stmt = $db->prepare($sql);
$stmt->bind_param("i", $row_sid );
$stmt->execute();
$result = $stmt->get_result()->fetch_array();
$stmt->close();
对于最坏的情况,此查询需要 2 秒,其中scans
表具有超过 20000 个点且相应的row_sid = 10
,但这仅在使用mysqli_stmt::bind_param()
时发生。
如果我自己运行查询:
select ts from scans where sessionid = 10 order by id desc limit 1;
它在 0.016 秒内返回。
如果我不使用绑定参数,则相同:
$sql = "select ts from scans where sessionid = 10 order by id desc limit 1";
$stmt = $db->prepare($sql);
$stmt->execute();
$result = $stmt->get_result()->fetch_array();
$stmt->close();
这也以毫秒为单位返回。
按照扫描表详细信息:
SHOW CREATE TABLE
scans | CREATE TABLE `scans` (
`id` int NOT NULL AUTO_INCREMENT,
`lid` int DEFAULT NULL,
`devid` int DEFAULT NULL,
`sessionid` int DEFAULT NULL,
`ts` int DEFAULT NULL,
`irpwr` double DEFAULT NULL,
`ir_v` double DEFAULT NULL,
`ir_i` double DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `scans_sessionid` (`sessionid`),
KEY `scans_devlid` (`devid`,`lid`),
KEY `scans_ts` (`ts`),
KEY `scans_lid` (`lid`)
) ENGINE=InnoDB AUTO_INCREMENT=43769072 DEFAULT CHARSET=utf8
编辑:
我使用PDO而不是mysqli进行了测试,并且使用bindValue()
和bindParam()
都返回了接近直接查询速度的性能。 虽然,我没有找到任何信息显示性能差异的原因,因为 mysqli 在基准测试中被证明更快。
我可能遇到了一个我不明白的错误。
要“证明”“绑定”有问题,请在 PHP 代码中添加microtime(true)
以分离出对绑定的调用。
要计时任何 SQL 查询,请运行两次。 有多个缓存会干扰获取实际时间。
如果数据还没有缓存到 buffer_pool(或其他 RAM 缓存)中,第一次运行会因为 I/O 而变慢; 第二个将是对查询的生产使用的实际估计。
如果“查询缓存”为 ON,则第二次将在 1 毫秒左右,无论查询有多复杂。 QC 即将离开; 计划其未来的拆除。 同时,做SELECT SQL_NO_CACHE...
然后计时。
回到具体的查询...
select ts
from scans
where sessionid = ?
order by id desc
limit 1
会跑得更快
INDEX(session_id, id, ts)
添加时,还将现有的 INDEX(session_id) 删除为多余的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.