2014-12-02 60 views
4

我的应用程序首先查询2个大型数据集,然后对第一组数据做一些工作,然后在第二组数据上“使用”它。PHP异步mysql查询

如果可能的话,我希望它只是同步查询第一个集合,第二个集合是异步查询的,对第一个集合进行处理,然后等待第二个集合的查询完成最后使用它上面的第一组数据。

这是可能以某种方式?

回答

13

这是可能的。

$mysqli->query($long_running_sql, MYSQLI_ASYNC); 

echo 'run other stuff'; 

$result = $mysqli->reap_async_query(); //gives result (and blocks script if query is not done) 
$resultArray = $result->fetch_assoc(); 

或者你可以使用mysqli_poll,如果你不希望有一个阻塞调用

http://php.net/manual/en/mysqli.poll.php

+0

看起来很容易。但是有没有办法用PDO而不是mysqli来做? – Clox 2014-12-02 01:59:38

+4

@Clox我建议你在你的问题或标题中包含PDO,如果这是一个要求。 – EternalHour 2014-12-02 02:13:51

+0

@Clox:我没有意识到类似的PDO方法,但你总是可以使用异步curl请求:https://github.com/barbushin/multirequest->创建两个php脚本,每个执行一个查询,然后调用这些脚本与curl异步。我不是说这是最优雅的解决方案,但它的工作原理。 – Thorsten 2014-12-02 02:18:36

9

MySQL的要求,一个连接里面,查询完全处理before the next query is launched。那includes the fetching of all results

这是可能的,但是,到:

  • 通过建立多个连接

默认情况下,在一次

  • 推出多个查询获取结果的一个,而不是所有的一个,PHP将等待直到全部结果可用,然后在内部(在mysql驱动程序中)一次获取所有结果。即使在使用例如PDOStatement::fetch()将其一次一行地导入到您的代码中时也是如此。使用PDO时,可以通过将属性\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY设置为false来防止这种情况。这是有用的:

    请注意,速度通常受到存储系统的限制,其特征意味着两个查询的总处理时间在同时运行时的总处理时间大于逐个运行它们的总处理时间。

    一个例子(可以完全做到在MySQL,但表示其原理...):

    $dbConnectionOne = new \PDO('mysql:hostname=localhost;dbname=test', 'user', 'pass'); 
    $dbConnectionOne->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); 
    
    $dbConnectionTwo = new \PDO('mysql:hostname=localhost;dbname=test', 'user', 'pass'); 
    $dbConnectionTwo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); 
    $dbConnectionTwo->setAttribute(\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); 
    
    $synchStmt = $dbConnectionOne->prepare('SELECT id, name, factor FROM measurementConfiguration'); 
    $synchStmt->execute(); 
    
    $asynchStmt = $dbConnectionTwo->prepare('SELECT measurementConfiguration_id, timestamp, value FROM hugeMeasurementsTable'); 
    $asynchStmt->execute(); 
    
    $measurementConfiguration = array(); 
    foreach ($synchStmt->fetchAll() as $synchStmtRow) { 
        $measurementConfiguration[$synchStmtRow['id']] = array(
         'name' => $synchStmtRow['name'], 
         'factor' => $synchStmtRow['factor'] 
        ); 
    } 
    
    while (($asynchStmtRow = $asynchStmt->fetch()) !== false) { 
        $currentMeasurementConfiguration = $measurementConfiguration[$asynchStmtRow['measurementConfiguration_id']]; 
        echo 'Measurement of sensor ' . $currentMeasurementConfiguration['name'] . ' at ' . $asynchStmtRow['timestamp'] . ' was ' . ($asynchStmtRow['value'] * $currentMeasurementConfiguration['factor']) . PHP_EOL; 
    } 
    
  • +0

    优秀的,很好解释的答案!刚刚学到了新的东西:) – Darren 2014-12-02 03:47:44

    +1

    考虑到PDO实际上不支持本地异步操作,我认为这个答案很混乱。您应该改用MYSQLI。 – EdNdee 2015-05-23 07:26:33