Dovresti abbandonare un framework ORM quando devi implementare un'operazione bulk?

15

Ecco una situazione comune:

  • È necessario implementare un'operazione di massa in un'applicazione che utilizza un framework ORM.
  • Dopo il primo passaggio, hai notato notevoli problemi di prestazioni.

Ecco la mia domanda:

  • In questa situazione, dovresti favorire una soluzione che includa SQL raw?
  • O ci sono modelli di progettazione ben noti che possono aiutarti a mitigare i problemi che sono comunemente associati alle operazioni di massa con i framework ORM?

Modifica

  • Non sto chiedendo se dovresti rimuovere il framework ORM dall'intera applicazione.
  • Mi sto chiedendo: dovresti rinunciare al framework ORM per questa piccola parte dell'applicazione?
posta Jim G. 10.11.2011 - 16:02
fonte

8 risposte

13

Gli ORM non sono concepiti per l'accesso completo al tuo database. Usali per quell'80% di codice che è CRUD, la roba troppo noiosa per scrivere da sola. Utilizza stored procedure, SQL dinamico o qualsiasi altra cosa desideri per il restante 20% che deve essere attentamente ottimizzato.

    
risposta data 10.11.2011 - 16:35
fonte
7

Uso un ORM (nibernate) in un'applicazione che richiede prestazioni elevate e gestisce miliardi di record. Con il tempo abbiamo notato che i problemi di prestazioni più significativi erano legati al nostro modo di utilizzare l'ORM piuttosto che a causa dell'ORM da solo.

L'ORM non dovrebbe sostituire la conoscenza obbligatoria del database. È uno strumento che utilizzi per ottenere maggiore produttività e flessibilità nel codice, ma dovrai conoscere i processi sottostanti per ottimizzare le tue prestazioni.

Non hai specificato un ORM specifico, quindi ecco le cose che abbiamo fatto per migliorare le prestazioni:

  • Abbiamo usato un profiler ORM. (abbiamo usato nhprof)
  • Abbiamo usato un profiler del database. (abbiamo usato SQL Server Profiler)
  • Leggiamo tutti gli articoli che possiamo sull'argomento. (Molti erano disponibili per NHibernate oltre all'intero capitolo sull'argomento nella documentazione)
  • Abbiamo acquistato libri specifici su prestazioni e amp; scalabilità.
  • Abbiamo creato un sistema di benchmarking per testare le nostre ottimizzazioni.
  • e, cosa più importante, siamo stati in grado di testare il nostro codice con clienti reali con enormi dati. Quest'ultima cosa ci ha aiutato a individuare la maggior parte dei problemi nella nostra applicazione.
risposta data 10.11.2011 - 16:31
fonte
1

Siamo riusciti a farlo con Entity Framework, ma la nostra applicazione ha fatto un sacco di operazioni in stile batch (avremmo scritto un numero elevato di record in singole tabelle), quindi è stata una buona idea. Sicuramente vedrei se sarebbe possibile mantenere il framework ORM se possibile, solo per ridurre la quantità di codice per scopi speciali nella tua app. È possibile eseguire il buffer delle scritture, quindi eseguirle come gruppo? Perdi la semantica della transazione, ma se stai andando con operazioni collettive presumo tu abbia già fatto i conti con quello.

    
risposta data 10.11.2011 - 16:32
fonte
1

Gli ORM non fanno nulla di magico. Traducono i metodi di accesso agli oggetti in SQL. Le istruzioni SQL eseguite non sono necessariamente più lente dell'SQL che si scrive manualmente. Detto questo, ci sono alcuni problemi su cui potresti imbatterti:

  1. Transazioni: una grande operazione di massa è quasi sempre più veloce di molte piccole transazioni che insieme realizzano la stessa cosa. Quindi, se le chiamate del metodo ORM utilizzano transazioni a grana fine (i metodi attivi in stile record nelle entità Spring Roo, ad esempio, sono annotati come @Transactional per impostazione predefinita), le operazioni di massa saranno lente. Se questo è il caso nella tua applicazione, dovresti esaminare la tua logica di transazione.
  2. Memorizzazione nella cache: in Hibernate, una cache di primo livello consente al gestore di entità di evitare viaggi di andata e ritorno al database non necessari. La cosa buona in generale, ma negativa per gli inserimenti di massa, dove porta a intasamenti della cache inutili, con conseguente degrado delle prestazioni delle applicazioni. Se questo è il tuo problema, dovresti guardare il modello di Batching suggerito sopra da ChrisAnnODell. Lo usiamo nei nostri importatori e velocizza molto gli inserimenti di massa.

Non c'è niente di sbagliato nell'usare SQL nativo per migliorare le prestazioni. Ma prima assicurati di capire cosa ti sta rallentando.

    
risposta data 10.11.2011 - 18:05
fonte
1

Ignora l'ORM. Non solo, ma anche bypassare "regolari" sql. Utilizzare un'utilità bulk del database per inserire set di dati estremamente grandi su una tabella di staging. Quindi utilizza sql per eseguire le attività di gestione temporanea.

Il tuo ORM "flavor-of-the-blog" potrebbe non funzionare in tutte le situazioni.

    
risposta data 11.11.2011 - 04:53
fonte
0

Sei stato in quella situazione. A volte, devi.

Alcuni O.R.M. consente allo sviluppatore di saltare il modello dell'oggetto e andare direttamente al livello del database.

Ci sono anche O.R.M., che usano operazioni bulk, incapsulate, come Object Oriented.

    
risposta data 11.11.2011 - 00:46
fonte
0

Come menzionato da umlcat , ci sono alcuni ORM che ti permetteranno di utilizzare le operazioni di massa.

Ancora meglio, molti ORM sono estensibili, quindi puoi semplicemente scrivere il tuo metodo per eseguire operazioni bulk, se non già supportato. Se l'operazione di massa nella tua applicazione è qualcosa che puoi trarre in considerazione, la aggiungo come strato sull'ORM (per fare ciò, probabilmente dovrai scrivere SQL raw), ma nell'applicazione, usa l'ORM metodo che hai implementato.

Questo facilita anche il test delle unità e il debugging. Una volta che hai una buona copertura di test per i tuoi metodi ORM, sei libero di usarlo nelle tue app. Altrimenti, il debug di SQL raw (specialmente quelli grandi con transazioni e molti JOIN) può essere un problema.

Una volta mi ci è voluto quasi un giorno per individuare un bug in una chiamata SQL raw che era quasi 100 LOC, e il bug era solo un singolo personaggio! Da allora, cerco di evitare di avere SQL raw nell'app e di testare tutte le procedure SQL separatamente.

    
risposta data 11.11.2011 - 01:52
fonte
0

Beh, non ci sono motivi di design di cui sono a conoscenza. La mia ipotesi è che tu abbia preso la decisione per l'ORM per un motivo, quindi abbandonare l'ORM probabilmente non è quello che vuoi. Tuttavia, in questi casi penso che ci sia spazio per il mix di entrambe le soluzioni. Non c'è niente di sbagliato in questo, fintanto che lo fai in modo cosciente e documenta perché ti allontani dall'uso predefinito dell'ORM nel tuo software. Inoltre, alcuni framework ORM dispongono di alcune funzionalità per eseguire operazioni bulk. So che nHibernate (ORM per il framework .NET) ha le cosiddette StatelessSessions, che hanno un sovraccarico molto minore, ma questo potrebbe non darti ancora il boost di perfomance che stai cercando. In tal caso, usa solo SQL raw.

    
risposta data 10.11.2011 - 16:18
fonte

Leggi altre domande sui tag