我的应用程序是一个数字标牌播放器。我们需要定期将远程游戏数据发送回云端。缓存播放数据证明以帮助解决网络中断问题。
玩家可以在一天内轻松创建6,000个POP记录。当网络重新启动时,这会导致从一个演示文稿移动到另一个演示文稿的相当严重的延迟。
我当时正在尝试使用MySql的异步模式来尝试缓解这种延迟......但我认为它并不像我认为的那样。
我正在循环一个大的结果集,我仍然需要等待该循环才能完成。我是否捆绑了6,000个插件并一次发送所有插件?如果我还在等待异步数据库调用,我的AJAX会在什么时候返回结果?它是否显然不能以这种方式工作?谷歌返回的结果不到一页,文档并没有真正说明问题。
$sql = "SELECT MAX(time) from `pop` where `displayId` = ".$_GET['id'];
$res = $local->query($sql);
$row = $res->fetch_row();
//$log->lwrite("Last Updated is ".$row[0]);
$sql = "SELECT * FROM `pop`
WHERE `displayId` = ".$_GET['id']
." AND `time` > '".$row[0]."' LIMIT 1000";
$local->query($sql, MYSQLI_ASYNC);
if ($res = $local->reap_async_query()) {
while ($row = $res->fetch_row()) {
$log->lwrite(print_r($row, 1));
$sql = "INSERT INTO `pop`
(`displayId`, `time`, `duration`, `presId`)
VALUES ('".$row[1]."', '".$row[2]."', '".$row[3]."', '".$row[4]."')";
$remote->query($sql, MYSQLI_ASYNC);
}
}
我已经让自己屈服于这样一种观念,即我将不得不以不同的方式做到这一点。现在我只是好奇。 :)
我在这里错过了什么吗?
感谢您的时间和帮助。
答案 0 :(得分:0)
您是在谈论php服务器和DBMS之间的网络吗?在那种情况下,你真的不明白async mysqli。
使用异步查询的目的是在不阻止PHP代码的情况下应用DML。它不打算将命令排队到可能定期脱机的系统。您也不应该直接在互联网上公开DBMS。它提供了一个窗口,您可以使用php代码执行其他操作(例如运行其他查询或将数据发送到客户端)。脚本完成后,它无意对数据执行操作。
有很多方法可以解决这个问题,其中大部分都涉及在连接的两端运行守护进程 - 这可能是大多数人的主要限制因素。您还没有说过对每个系统的控制权。妥协的解决方案是使用卫星系统上的工作。当然,您不应该尝试在Web处理程序中复制数据。
您是否尝试在本地复制整个表格?如果是这样,为什么不使用MySQL的内置复制(通过VPN链接)。
答案 1 :(得分:-2)
代码的第一件事是您不应该在循环中执行INSERT语句。正确的方法是在单个INSERT语句中将多个记录插入数据库。这仅受MySQL的max_allowed_packet设置限制,该设置限制了查询的长度。通常,它很大,可以轻松容纳6000条记录。
$sql = "SELECT * FROM `pop`
WHERE `displayId` = ".(int)$_GET['id']
." AND `time` > '".$local->real_escape_string($row[0])."' LIMIT 1000";
$res = $local->query($sql) or die($local->error);// no async
$sql = '';
while ($row = $res->fetch_row()) {
$row = array_map(array($local, 'real_escape_string'), $row);// must have sanitization
if ($sql) $sql.= ',';// separate each record with a comma
$sql.= "('".$row[1]."', '".$row[2]."', '".$row[3]."', '".$row[4]."')"
$log->lwrite(print_r($row, 1));
}
$sql = "INSERT INTO `pop`
(`displayId`, `time`, `duration`, `presId`)
VALUES $sql";
$remote->query($sql, MYSQLI_ASYNC);// Do only one INSERT query instead of thousands
如果您在此处使用MYSQLI_ASYNC,PHP将不会等待插入完成,并且您的AJAX调用也将完成,而无需等待远程数据库查询完成。