diff --git a/documentation/src/main/docbook/manual/en-US/content/performance.xml b/documentation/src/main/docbook/manual/en-US/content/performance.xml index 802fcd5945..7e6ec02b74 100644 --- a/documentation/src/main/docbook/manual/en-US/content/performance.xml +++ b/documentation/src/main/docbook/manual/en-US/content/performance.xml @@ -456,10 +456,57 @@ Cat fritz = (Cat) iter.next(); <class name="Person" batch-size="10">...</class> - Hibernate will now execute only three queries: the pattern is 10, - 10, 5. + With this batch-size specified, Hibernate will now execute queries on demand when need to access the + uninitialized proxy, as above, but the difference is that instead of querying the exactly proxy entity that + being accessed, it will query more Person's owner at once, so, when accessing other person's owner, it may + already been initialized by this batch fetch with only a few ( much less than 25) queries will be executed. + - You can also enable batch fetching of collections. For example, if + This behavior is controlled by the batch-size and batch fetch style configuration. + The batch fetch style configuration ( hibernate.batch_fetch_style ) is a new performance + improvement since 4.2.0, there are 3 different strategies provided, which is legacy, + padded and dynamic. + + + + + LEGACY + The legacy algorithm where we keep a set of pre-built batch sizes based on + org.hibernate.internal.util.collections.ArrayHelper#getBatchSizes. + Batches are performed using the next-smaller pre-built batch size from the number of existing batchable identifiers. + In the above example, with a batch-size setting of 25 the pre-built batch sizes would be [25, 12, 10, 9, 8, 7, .., 1]. + And since there are 25 persons' owner to be initialized, then only one query will be executed using these 25 owners' identifier. + But in another case, suppose there are only 24 persons, there will be 3 queries (12, 10, 2) will + be executed to go through all person's owner, and the query will looks like : + + select * from owner where id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + select * from owner where id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + select * from owner where id in (?, ?) + + + + + PADDED + This is kind of similar with the legacy algorithm, it uses the pre-build batch sizes based on same + org.hibernate.internal.util.collections.ArrayHelper#getBatchSizes. The difference + is that here hibernate will use the next-bigger batch size and pads the extra identifier placeholders. + So, using the same example above, initializing 25 persons the query would be same as above, + only 1 query will be executed to batch query all the owners. + + However, the attempt to batch load 24 owners would result just a single batch of size 25, the + identifiers to load would be "padded" (aka, repeated) to make up the difference. + + + + + DYNAMIC + Dynamically builds its SQL based on the actual number of available ids. Does still limit to the batch-size defined on the entity. + + + + + + You can also enable batch fetching of collections. For example, if each Person has a lazy collection of Cats, and 10 persons are currently loaded in the Session, iterating through all persons will generate @@ -474,8 +521,8 @@ Cat fritz = (Cat) iter.next(); </set> </class> - With a batch-size of 3, Hibernate will load 3, - 3, 3, 1 collections in four SELECTs. Again, the value + For example, with a batch-size of 3 and using legacy batch style, + Hibernate will load 3, 3, 3, 1 collections in four SELECTs. Again, the value of the attribute depends on the expected number of uninitialized collections in a particular Session.