Dubbi correlati alle prestazioni in Java con Hibernate

6

Supponiamo che in alcuni progetti basati su ORM (per esempio Hibernate) io stia cercando di recuperare solo poche colonne piuttosto che l'intero Oggetto con più di 20 attributi. Sto scrivendo HQL come "select attr1, attr2 from Entity " . So che non sto approfittando dell'uso di Hibernate perché otterrò il risultato solo in forma Oggetto e quindi devo fare il casting esplicito per questo. Ma se sarà un approccio corretto per ottenere l'ottimizzazione dal database prospettico o perché sto facendo un casting esplicito il costo sarà ancora lo stesso?

    
posta Logicalj 06.09.2013 - 15:07
fonte

4 risposte

7

Se non riscontri problemi di prestazioni durante il recupero di tutti gli attributi di entità, non perdere tempo nella micro-ottimizzazione.

A meno che gli attributi non siano molto grandi, probabilmente non vedrai alcuna differenza di prestazioni nella selezione delle sole colonne di cui hai realmente bisogno per una determinata operazione rispetto a tutte le colonne.

Se sei davvero preoccupato di questo, credi che causerà problemi di prestazioni e vorresti superare questi problemi, esegui alcuni test (con molte iterazioni per ottenere tempi medi) per confrontare il costo del recupero di tutti gli attributi contro solo quelli di cui hai bisogno. Ci vorrà meno tempo per scrivere i test di quanto pensi, e ne varrà la pena per ottenere i dati per il backup della tua decisione.

Se ottieni i dati per provare i problemi di prestazioni che stai assumendo, e la differenza di prestazioni è abbastanza grande da fare la differenza nella tua specifica applicazione , allora ha senso iniziare le ricerche come migliorare le prestazioni.

    
risposta data 06.09.2013 - 15:55
fonte
2

Hibernate e altri strumenti ORM sono fantastici e ti consentono di ottenere l'80% del tempo per un'applicazione completa. Nell'esempio se attr1 e attr2 sono valori primitivi letti da una colonna, non mi preoccuperei di cosa stia facendo Hibernate, probabilmente incorre in un sovraccarico di lavoro senza Hibernate quando si esegue iterazione sul ResultSet. Se attr1 e attr2 sono il risultato di un join, è possibile rendere la raccolta risultante pigra caricata, il che significa che le variabili vengono popolate con oggetti proxy fino a quando i dati non vengono richiesti e a quel punto (data la transazione è ancora aperta) tornano al database per recuperare i valori.

Tuttavia. Hibernate crea alcune query abbastanza brutte (sub-ottimali) e molto spesso usa molte query. Se si attiva la registrazione su DEBUG per Hibernate, è possibile che si verifichi ciò che si prevede essere una singola query eseguita come selezioni multiple. È a questo punto che la tua performance potrebbe essere un collo di bottiglia (a seconda che tu l'abbia visto arrivare o meno) e staresti meglio usando JdbcTemplate con tutti i join modellati come più ottimali per la tua origine dati.

In fin dei conti il mixaggio delle due tecniche è valido e comune.

Come sempre, se non è lento, non aggiustarlo!

    
risposta data 06.09.2013 - 15:44
fonte
0

I know i am not taking advantage of using Hibernate [...]

Hibernate è un po 'più di un semplice ORM automatico che dovrebbe mappare oggetti Java completi a tabelle di database complete. Fornisce la mappatura di tutte le operazioni, non solo delle query; inserisce ed elimina i lavori in modo diretto, anche se non si desidera inserire un oggetto completo nel database. Inoltre, Hibernate viene fornito con cache di livello 2 (Ehcache) che migliora significativamente le prestazioni.

Riguardo alla selezione dei soli oggetti di cui hai bisogno; L'ibernazione comporta anche miglioramenti. Per esempio, io, uno sviluppatore di OO, ho più familiarità con il modello di oggetto piuttosto che con uno sviluppatore di database che ha familiarità con SQL e le relazioni; Hibernate mi viene in aiuto lasciandomi usare un linguaggio di query più object-friendly (HQL, JPQL). Inoltre, anche se non sa mappare certe tabelle in un'altra classe, la converte comunque in una matrice (o lista di matrici, se in una query vengono restituite più voci); non hai ancora bisogno di ottenere ResultSet e iterare su di esso.

Un'altra alternativa è l'utilizzo del recupero pigro e la chiamata al database verrà effettuata solo quando si chiama effettivamente il metodo. Se non sono necessari determinati campi, impostarli come pigri e, se non sono necessari, non vengono recuperati.

Come ultime parole, devo dire che gli strumenti ORM automatici come Hibernate sono buoni e migliorano notevolmente la produttività, ma non sono una pallottola d'argento. Non sono adatti in tutti gli scenari; se vuoi caratteristiche di database speciali o non hai a che fare con un dominio abbastanza complesso, probabilmente stai meglio con il buon vecchio JDBC o con la migliore alternativa di Spring, JdbcTemplate .

    
risposta data 06.09.2013 - 15:38
fonte
0

Se vuoi selezionare solo alcune colonne, puoi fare qualcosa come Select new x.y.z.Object(c.column1, c.column2) FROM Object c

Ovviamente dovresti dichiarare un costruttore con solo quei due campi. Se si analizzano i registri, si vedrà che solo le colonne necessarie vengono recuperate da de DB. Per quanto posso dire, questo è un caso d'uso perfettamente valido insieme all'utilizzo del recupero esplicito (a volte sono necessarie delle ottimizzazioni come questa).

Spero che ti aiuti

    
risposta data 06.09.2013 - 15:54
fonte

Leggi altre domande sui tag