Mysqli异步 - 它是如何工作的?

时间:2014-12-19 21:41:42

标签: php asynchronous mysqli

我的应用程序是一个数字标牌播放器。我们需要定期将远程游戏数据发送回云端。缓存播放数据证明以帮助解决网络中断问题。

玩家可以在一天内轻松创建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);
    }
}

我已经让自己屈服于这样一种观念,即我将不得不以不同的方式做到这一点。现在我只是好奇。 :)

我在这里错过了什么吗?

感谢您的时间和帮助。

2 个答案:

答案 0 :(得分:0)

您是在谈论php服务器和DBMS之间的网络吗?在那种情况下,你真的不明白async mysqli。

使用异步查询的目的是在不阻止PHP代码的情况下应用DML。它不打算将命令排队到可能定期脱机的系统。您也不应该直接在互联网上公开DBMS。它提供了一个窗口,您可以使用php代码执行其他操作(例如运行其他查询或将数据发送到客户端)。脚本完成后,它无意对数据执行操作。

有很多方法可以解决这个问题,其中大部分都涉及在连接的两端运行守护进程 - 这可能是大多数人的主要限制因素。您还没有说过对每个系统的控制权。妥协的解决方案是使用卫星系统上的工作。当然,您不应该尝试在Web处理程序中复制数据。

您是否尝试在本地复制整个表格?如果是这样,为什么不使用MySQL的内置复制(通过VPN链接)。

答案 1 :(得分:-2)

代码的第一件事是您不应该在循环中执行INSERT语句。正确的方法是在单个INSERT语句中将多个记录插入数据库。这仅受MySQL的max_allowed_pa​​cket设置限制,该设置限制了查询的长度。通常,它很大,可以轻松容纳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调用也将完成,而无需等待远程数据库查询完成。