5

私はデータベースの経験がなく、「n + 1 selects issue」について読んだばかりです。フォローアップの質問:データベースがプログラムと同じマシンにあり、RAM にキャッシュされ、適切にインデックスが作成されていると仮定すると、n+1 クエリ パターンが遅いのはなぜですか?

例として、受け入れられた回答からコードを取り上げましょう。

SELECT * FROM Cars;

/* for each car */
SELECT * FROM Wheel WHERE CarId = ?

私のデータベース キャッシュのメンタル モデルでは、各SELECT * FROM Wheel WHERE CarId = ?クエリに次のものが必要です。

  • "Wheel" テーブルに到達するための 1 回のルックアップ (1 つのハッシュマップget())
  • CarId指定された(別の hashmap get())を持つ k ホイールのリストに到達するための 1 回のルックアップ
  • 一致する各ホイールのホイール行を取得するための k 回のルックアップ (k ポインターの参照解除)

内部メモリ構造のために追加のオーバーヘッドのために小さな定数係数を掛けたとしても、それでも目立たないほど高速になるはずです. プロセス間通信がボトルネック?


編集: Hacker News でこの関連記事を見つけました: Postgres Internals による Select ステートメントの追跡。- HN ディスカッション スレッド

編集2:明確にするために、私大きいと思いますN。自明ではないオーバーヘッドが追加されると、顕著な遅延が発生します。上記の設定で、そもそもオーバーヘッドがそれほど重要ではない理由を尋ねています。

4

4 に答える 4

5

あなたが説明したシナリオでは、n + 1の選択を避けることはそれほど重要ではないということは正しいです。データベースがリモート マシン上にある場合、1 ミリ秒を超える通信遅延が一般的です。つまり、CPU は数百万のクロック サイクルをネットワークの待機に費やします。

同じマシン上にいる場合、通信遅延は数桁小さくなりますが、別のプロセスとの同期通信にはコンテキストの切り替えが必要であり、通常は 0.01 ミリ秒 ( source ) を超えるコストがかかります。これは数万クロック サイクルです。

さらに、ORM ツールとデータベースの両方で、クエリごとにいくらかのオーバーヘッドが発生します。

結論として、データベースがローカルの場合、n+1 の選択を回避することはそれほど重要ではありませんが、n が大きい場合は依然として重要です。

于 2014-10-14T09:08:57.460 に答える