2014-12-02 88 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