Hibernateは、N + 1問合せの問題を回避するための(少なくとも)2つのオプションを提供します。 1つはFetchModeをSubselectに設定することで、このIN節内にIN節と副選択を含む選択を生成します。もう1つはBatchSizeを指定することです。これは、親のIDを含むIN節で選択を生成します。Hibernate Subselect vs Batch Fetchching
どちらも機能しますが、Subselectオプションは、親が複雑であるために、パフォーマンス上の問題が発生することがよくあります。一方、大きなBatchSize(1000など)では、クエリの数とそれらのクエリの複雑さは非常に小さいです。
私の質問は、HibernateのSubselect FetchModeをBatchSizeよりいつ使用するのですか? Subselectは親エントリが非常に多く(数千)、SubselectをBatchSizeにしたい場合はおそらく理にかなっています。
EDIT:熱心な負荷を扱う場合、2つの違いがあることに気付きました。 xToManyアソシエーションが熱心に、かつ副選択を通してロードされるように設定されている場合、それは怠け者であった場合と同じように副選択を生成します。ただし、BatchSizeを指定すると、生成されたクエリでは、別のクエリではなく外部結合が使用されます。熱心にロードする際にHibernateに別のバッチクエリを使用させる方法はありますか?
なぜsubselectを制御するのが難しいのか分かりません。いくつかの光を投げることができますか? –
副選択は、以前に実行されたクエリに依存します。このクエリは非常に複雑である可能性があります。他の多くの表を使用し、索引付けされていない列でフィルタリングします。したがって、サブクエリのアプローチがパフォーマンスを向上させる可能性が高いかどうかは言い難いです。 –
副選択に関するもう1つの問題は、MySQLで解決できます。 MySQL(5.5以下)は、ネストされたクエリを使用して強制的に相関関係を作成し、親クエリのすべての行についてそれらを再評価するため、ネストされたクエリでは驚異的なパフォーマンスを示します。私は、Hibernateが注釈付きリレーションのネストされたクエリを生成するための他の方法を見つけることができないので、副選択を避けると、MySQLで驚くようなことを防ぐことができます。 –