Мое приложение сначала запрашивает 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; }