web-dev-qa-db-ja.com

loadMultipleが各ノードを1つずつロードするよりも9.2倍速くノードをロードするのはなぜですか?

同時に複数のノードをロードする方が、1つずつロードするよりも高速であることを常に知っています。

私が知らなかったのは、ノードをロードする2つの方法の大きなパフォーマンスの違いです。

私は違いを見るために例を作りました。これが私の結果です:

1000ノードを1つずつロード:

$start_time = microtime(TRUE);
foreach (range(1, 1000) as $nid) {
  $node = \Drupal::entityTypeManager()->getStorage('node')->load($nid);
  if ($node) {
    print_r($node->id());
  }
}
$end_time = microtime(TRUE);
print_r($end_time - $start_time);

実行時間:10.7266秒。

同時に1000ノードをロード:

$start_time = microtime(TRUE);
$nids = [];
foreach (range(1, 1000) as $nid) {
  $nids[] = $nid;
}

$nodes = \Drupal::entityTypeManager()->getStorage('node')->loadMultiple($nids);

foreach ($nodes as $node) {
  if ($node) {
    print_r($node->id());
  }
}
$end_time = microtime(TRUE);
print_r($end_time - $start_time);

実行時間:1.1664秒。

ノードを1つずつロードする場合よりもloadMultipleを9.2倍高速にするにはどうすればよいですか?

Drupalとデータベースの間の接続ですか?ノードを1つずつロードするときにプロセスを遅くしている他の要因は何ですか?

ロードされたノードがキャッシュされないようにするために、すべてのリクエストの後にキャッシュをクリアしました。

microtime関数を使用して、正確な実行時間を計算しました。

4
user72672

個々のノードをロードする場合は、エンティティタイプマネージャーをロードしている可能性があります。その後、各ノードでストレージを取得し、クエリを実行してノードデータを取得し、ノードを構築します。マルチプロセスでは、DBクエリの一部が組み合わされている可能性が高く、処理はコードを複数回実行する必要がなく、バッチで行われます。

6
Jaypan