問題タブ [select-n-plus-1]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
hibernate - JPa と Hibernate を使用した双方向の 1 対 1 での N+1 の問題
実行されるクエリは次のとおりです。
注文書でのマッピング:
ShoppingBasket でのマッピング:
そのクエリが実行されると、次のクエリに変換されます。
-- 次のタイプの 1 つのクエリ。指定されたステータスのすべてのバスケットと注文を取得します。
-- 次のタイプの n 個のクエリ。関連する注文を取得するために、前のクエリのバスケット結果ごとに 1 つ
フェッチ戦略を変更してみました (とにかく HQL を使用すると無視されることはわかっています)、フェッチ計画を変更し、絶望から「オプション」属性を変更しました。Hibernate に PurchaseOrders を関連付けられた ShoppingBaskets と共に単一のクエリでロードさせる方法はありますか? それを達成するためにバイトコード計測を使用する必要がありますか?
Hibernate デバッグ ログは次のとおりです。
hibernate - n+1 クエリが機能しない
以下のコードでは、クエリの問題が発生することを期待していn+1
ますが、発生していません。
ユーザー.java :
PhoneNumber.java :
User.hbm.xml :
phoneNumber.hbm :
hibernate.cfg :
HQLClient.java :
出力は次のとおりです。
ユーザーIDへの電話番号レコードごとに個別のselectステートメントがあると予想していましたが、3 Phonenumber-1 useridの場合、[(3 + 1)の代わりに]1つのselectステートメントがあります。なぜこのように来るのですか?
ありがとう!
sql - n+1 選択パターンが遅いのはなぜですか?
私はデータベースの経験がなく、「n + 1 selects issue」について読んだばかりです。フォローアップの質問:データベースがプログラムと同じマシンにあり、RAM にキャッシュされ、適切にインデックスが作成されていると仮定すると、n+1 クエリ パターンが遅いのはなぜですか?
例として、受け入れられた回答からコードを取り上げましょう。
私のデータベース キャッシュのメンタル モデルでは、各SELECT * FROM Wheel WHERE CarId = ?
クエリに次のものが必要です。
- "Wheel" テーブルに到達するための 1 回のルックアップ (1 つのハッシュマップ
get()
) CarId
指定された(別の hashmapget()
)を持つ k ホイールのリストに到達するための 1 回のルックアップ- 一致する各ホイールのホイール行を取得するための k 回のルックアップ (k ポインターの参照解除)
内部メモリ構造のために追加のオーバーヘッドのために小さな定数係数を掛けたとしても、それでも目立たないほど高速になるはずです. プロセス間通信がボトルネック?
編集: Hacker News でこの関連記事を見つけました: Postgres Internals による Select ステートメントの追跡。- HN ディスカッション スレッド。
編集2:明確にするために、私は大きいと思いますN
。自明ではないオーバーヘッドが追加されると、顕著な遅延が発生します。上記の設定で、そもそもオーバーヘッドがそれほど重要ではない理由を尋ねています。
java - @ManyToOne JPA アノテーション付きプロパティの N+1 クエリを作成する Hibernate
私はこれらのクラスを持っています:
このクエリを実行すると:
InvoiceItem からレコードを選択するために 1 つのクエリを実行し、10000 の請求書アイテムがある場合、各 InvoiceItem から請求書を選択するために 10000 の追加クエリを生成します。
すべてのレコードを 1 回の SQL でフェッチできれば、もっと良いと思います。実際、なぜそれがデフォルトの動作ではないのか不思議に思います。
それで、どうすればそれを行うことができますか?
sql - Rails 4、ActiveRecord SQL サブクエリ
A:parent has_many :children
と私は、親の最年長の子供の年齢を の属性として取得しようとしていますparent
。私は、それを効率的に達成するあらゆるソリューションを受け入れます。
サブクエリを実行しようとしている理由は、n+1
親ごとに個別の DB 要求を行うのではなく、DB にオーバーヘッドを任せるためです。どちらも非効率的ですが、サブクエリを使用する方が効率的です。
ユースケースの例:
私の試み:
これは、すべての親の最大年齢の配列を返します。これを 1 つの親だけに制限するか、すべての親を取得するときに親の属性として含めるようにしたいと考えています。
更新 2015-06-19 11:00
これが私が思いついた実行可能な解決策です。より効率的な代替手段はありますか?
使用例:
java - コレクションをフェッチした後にエンティティをクエリするHibernate
以下の2クラスがあります
他のクラス プロパティやエンティティ アノテーションなどの詳細の一部は、例を正確にするために省略されています。詳細が必要な場合はお知らせください。はい、StagingConceptDescription から StagingConcept への FK は非 PK 外部キーです。
基準を作成する場合:
1 つのクエリで DB からすべての StagingConcept エンティティを取得します。しかし、descriptions
StagingConcept ごとに取得する必要があります。そのために、クエリを作成します。
結果の SQL は次のようになります。
その SQL の結果セットはわずかに大きくなりますが、すべての StagingConcept とその説明をフェッチします。
ここまでは問題ないようです。しかし、その後、すべての説明のステージング コンセプトを再び見つけようとします。したがって、30000 個のステージング コンセプトと 60000 個の説明がある場合、すべての説明のステージング コンセプトを取得するために、さらに 60000 個のクエリが送信されます。これは少し厄介に見え、トランザクションのタイムアウトを過ぎて実行するのに十分な時間がかかります。
この問題を解決するために、StagingConceptDescription を次のように変更します。
そのため、ManyToOne 関係は明示的に LAZY に設定されています。また、関係がオプションではないことを示すために、概念がオプションではないことを関係が述べています。これを設定することで、関係のもう一方の端が常に存在するため、必要に応じてプロキシ オブジェクトを作成しても問題ないことを hibernate に伝えるつもりでした。しかし、これはどれも効果がありませんでした。これが機能するかどうかはよくわかりません。
注釈なども試しましたが@Fetch
、どれも機能しません。に設定し@LazyToOne(LazyToOneOption.PROXY)
ても効果はありませんでした。
java - select n + 1 を自動的に解決する
これは、pht の ORM における select n + 1 問題の簡単な例を提供しますが、考え方は他の言語の ORM でも同じであるはずです。
典型的な解決策は、熱心な読み込みを使用してクエリを 1 つに減らすことです。これはそれほど難しいことではないと思いますが、OTOH、後者のリファクタリングでは開発者が 2 つの場所を変更する必要があるため、非常に脆弱です。それ以外の場合は、この select n + 1 問題が再発します。
私の直感では、パス分析を行って、これらの子属性がコードの後半で使用されることを把握できるはずです。そのため、必要なすべての情報を一度に収集するクエリを生成しましょう。
これは、Ruby や php などの解釈された言語を使用して実装された ORM を要求するには、おそらく多すぎるでしょう。しかし、Java (NHibernate) も C# (エンティティ フレームワーク) も、このパス分析を行っていません。どうしてこれなの?
django - djangoアプリでn + 1クエリを自動的に識別する方法は?
Django アプリケーションで n+1 クエリを識別するために使用できるツール、プラグイン、または手法はありますか? n+1 クエリを識別し、さまざまな方法で警告をログに記録したりポップアップしたりする Rails 用の bullet と呼ばれる gem がありますが、Django に似たものを見つけることができませんでした。既存のソリューションを誰も知らない場合は、独自のプラグインを作成する方法についてのガイダンスを受け入れます。