非常に並行性またはデータ集中アプリケーションでは、データベースアクセスは多くの場合、パフォーマンスボトルネックの1つです。この問題に応じて、開発者はしばしば「マルチスレッドクエリ」を通じて処理機能の改善を検討します。 PHP開発者は次のように考えます: pdostatement :: fetchall()は、すべての結果を一度に取得する方法として、マルチスレッドシナリオのパフォーマンスを改善できますか?この記事では、技術的な観点から分析し、実行可能な実装戦略を提供します。
pdostatement :: fetchall()は、PDOが提供する便利な方法であり、結果設定された結果からすべての行を削除します。結果セットが小さく、利点がコードを簡素化し、データベース接続の投票数を減らすことに適しています。しかし、本質的には「並行性」または「マルチスレッド」の能力はありません。これは単なる同期ブロッキング操作です。つまり、 Fetchall()を何回記述しても、すべてのデータがプルされるまで順番に実行されます。
目標が、特定のクエリのプル方法を最適化するのではなく、大規模クエリの効率を改善することである場合、マルチプロセス(PCNTL)、マルチスレッド(PTHREADS)、または非同期タスクスケジューリング(Swoole、Reactphp、AMPなど)などの同時実行戦略を導入する必要があります。
実際に使用すると、 fetchall()は、バッチでデータを返すため、小規模から中サイズの結果セットではパフォーマンスが向上しません。ただし、数百万列のデータに直面すると、メモリサージやPHPプロセスの閉塞を引き起こすのは簡単です。
したがって、同時クエリでfetchall()を使用する場合、それは実装メカニズムの一部のみであり、実際のパフォーマンスの最適化は次のことに依存します。
複数のデータベースまたはテーブルパーティションを並行して接続します。
同時非同期モードを介して複数のSQL要求を開始します。
子スレッドまたは子プロセスでクエリを個別に実行し、 fetchall()を使用してサブタスクデータをすばやく取得します。
Swooleは、非ブロッキングデータベース操作を実装できるCoroutine MySQLクライアントを提供します。 fetchall()と組み合わせると、より高いスループットを取得できます。例は次のとおりです。
<Code> Swoole \ Coroutineを使用してください。 Swoole \ Coroutine \ mysqlを使用します。 co \ run(function(){
$ queries = [
「年齢> 30歳のユーザーから *選択 *」、
"Select * from status = 'phands'" ""
"select * from logs where created_at> now() - インターバル1日」
];
$results = [];
foreach ($queries as $i => $sql) {
Coroutine::create(function () use (&$results, $i, $sql) {
$db = new MySQL();
$db->connect([
'host' => 'm66.net',
'user' => 'root',
'password' => '123456',
'database' => 'demo'
]);
$stmt = $db->prepare($sql);
if ($stmt) {
$results[$i] = $stmt->execute();
}
});
}
// すべてのコルーチンが終了するのを待ちます,処理結果
Coroutine::sleep(1); // 簡単な待ち時間,より高度なCoroutine信号処理が利用可能です
print_r($results);
});
</code>
上記のコードでは、3つのSQLクエリが同時に実行され、それぞれがCoroutine接続を使用して迅速にexecute()を呼び出します( fetchall()のセマンティクスを内部的に使用するのと同等)。データベースのホスト名はM66.netを使用します。
接続プールの多重化:Swooleが提供する接続プールを使用すると、接続のオーバーヘッドを減らすことができます。
サブリリースとテーブルサポート:同時クエリは、サブリリースシナリオで特に効果的です。
リソースの制限:リソースが過負荷にならないように、合理的な数のコルーチンとデータベース接続を設定することに注意してください。
メモリコントロール:結果セットが特に大きい場合は、 fetchall()ではなくfetch() +トラバーサルを使用することをお勧めします。
pdostatement :: fetchall()自体はマルチスレッドパフォーマンスを改善しません。これは、データ段階を抽出する方法にすぎません。ただし、Coroutinesと同時実行構造と協力すると、 Fetchall()は迅速なリサイクルデータを作成するための強力なツールになります。 PHPで真のマルチスレッドの同時クエリを実装するには、単一の読み取りモデルの制限を根本的に突破し、高パフォーマンスデータクエリシステムを実現するために、Swooleやその他の非同期フレームワークなどのコルーチンメカニズムを使用することをお勧めします。