Мое приложение сначала запрашивает 2 больших набора данных, затем выполняет некоторую работу с первым набором данных и «использует» его во втором.
Если возможно, я бы хотел, чтобы вместо этого он запрашивал только первый набор синхронно, а второй — асинхронно, выполнял работу с первым набором, а затем ждал завершения запроса второго набора, если он еще не завершен, и, наконец, использовал первый набор. набор данных о нем.
Это возможно как-то?
Возможно.
$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, если вы не хотите иметь блокирующий вызов
MySQL требует, чтобы внутри одного соединения запрос был полностью обработан до запуска следующего запроса. Тот включает в себя получение все Результаты.
Однако возможно:
По умолчанию 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;
}