2009-08-12 14 views
6

Quando si esegue una query con NHibernate non sembra che si rispetti la dimensione del batch se è impostato su un numero superiore ai risultati effettivamente restituiti.nibernate alternate dimensione batch

Sto utilizzando l'ultima versione di NHibernate 2.1.0.4000 e GA di Linq su NHibernate. Ho una struttura di oggetti simile all'ordine che ha una collezione di OrderLines. I OrderLines sono stati definiti come una borsa con il seguente codice XML:

<bag name="OrderLines" access="field.camelcase" table="MyDatabase.OrderLines" lazy="true" batch-size="50"> 
    <key column="OrderId"/> 
    <one-to-many class="OrderLine"/> 
</bag> 

Se interrogo per gli Ordini e ottiene 50 risultati indietro seleziona correttamente tutte le OrderLines in una singola query, ma se ho meno di 50 risultati indietro non sembra rispettare le dimensioni del lotto definite.

E.g. Se ottengo 40 risultati indietro invece di 50 se eseguo 3 query con una dimensione batch di 25, 12 e 3

Sembra che stia tentando di indovinare la dimensione di batch corretta da utilizzare (ovvero fa 1/2 del batch prima la dimensione, poi 1/2 il resto ecc.). Mi aspetto che esegua una dimensione di batch di 50 tutto il tempo e se ce ne sono di meno rende la dimensione del batch più grande che può, in questo caso una dimensione del batch di 40.

Come posso ottenere il rispetto di NHibernate la dimensione del lotto che ho definito in tutti i casi?

risposta

10

Stavo inciampando per lo stesso strano comportamento. Ho scoperto che le persone inciampavano nella stessa cosa anche a Hibernate (Java).

Il comportamento è documentato qui per Hibernate:

http://opensource.atlassian.com/projects/hibernate/browse/HB-1457
https://forum.hibernate.org/viewtopic.php?p=2233747#2233747
https://forum.hibernate.org/viewtopic.php?p=2422139

Credo che questo comportamento è portato direttamente da Hibernate.

In breve:
ci sono solo poche istruzioni SQL per batch fechting preparato da Hibernate. Ciascuno con una dimensione batch fissa che definisce il conteggio dei parametri nella clausola IN. Hibernate quindi utilizza queste istruzioni preparate per soddisfare il caricamento in batch. Il numero specificato come dimensione del batch nel file di mapping, definisce solo il valore max. dimensione del lotto che può verificarsi.

Ad esempio, dimensione del lotto = 1000. Se hai 200 entità madri e vuoi caricare le collezioni figlio di queste, nHibernate decide di usare 4 istruzioni: una con 125, 62, 10 e 3 parametri nella clausola IN (somma fino a 200).

Tuttavia, se si hanno solo 125 entità padre, allora la sospensione decide di utilizzare solo un'istruzione, quella con 125 parametri.

(I numeri di cui sopra sono le mie osservazioni in NH 2.1)

La ragione di questo: (secondo la discussione legata forum)
preoccupazione per l'impatto negativo di creare molti PreparedStatements diverse quando i la dimensione massima del batch è grande. (PreparedStatements è un costrutto Java, mi chiedo se questa preoccupazione per le prestazioni sia altrettanto valida.NET)

Problemi correlati