2013-07-09 10 views
5

Ho appena testato la performance Eloquent ORM in Laravel e sono rimasto scioccato nel trovare una query semplice che richiede più di 3 secondi rispetto alla normale query di Laravel terminata in 0,1 secondi. Sto solo restituendo 1500 record.Prestazioni ORM eloquenti

DB::table('t_organisations')->get(); - 0.12253594398499 seconds 
Organisation::all(); - 3.6389181613922 seconds 

Sicuramente questo non può essere normale !? Non penso di aver perso qualcosa nel setup. Il mio db è normalizzato. Quale potrebbe essere il problema?

+0

Personalmente, l'avrei eseguito tramite XDebug per vedere dove si trova lo spreco di tempo. –

+1

Hai qualche relazione definita nel tuo modello? Se così fosse - Eloquent avrebbe bisogno di fare molti join ... – Laurence

+0

C'è sempre una cosa che è meglio usare Query Builder soprattutto quando si gestiscono dati di grandi dimensioni. – crynobone

risposta

2

Grazie per tutte le vostre risposte.

Ecco il risultato del log delle query mysql:

Organizzazione :: tutti(); - 1.6772060394287 secondi

130710 9:52:43  5 Connect [email protected] on seltec 
      5 Prepare set names 'utf8' collate 'utf8_unicode_ci' 
      5 Execute set names 'utf8' collate 'utf8_unicode_ci' 
      5 Close stmt  
      5 Prepare select * from `users` where `id` = ? limit 1 
      5 Execute select * from `users` where `id` = '2' limit 1 
      5 Close stmt  
      5 Prepare select * from `t_organisations` 
      5 Execute select * from `t_organisations` 
130710 9:52:44  5 Close stmt  
130710 9:52:45  5 Quit 

DB :: tavola ('t_organisations') -> get(); - 0.13963603973389 secondi

130710 9:55:16  6 Connect [email protected] on seltec 
      6 Prepare set names 'utf8' collate 'utf8_unicode_ci' 
      6 Execute set names 'utf8' collate 'utf8_unicode_ci' 
      6 Close stmt  
      6 Prepare select * from `users` where `id` = ? limit 1 
      6 Execute select * from `users` where `id` = '2' limit 1 
      6 Close stmt  
      6 Prepare select * from `t_organisations` 
      6 Execute select * from `t_organisations` 
      6 Close stmt  
      6 Quit 

Quindi nessuna differenza c'è poi .... il che significa che il ritardo deve trovarsi nel codice php Eloquente. Sì, ho installato xdebug e no non sono disposto a perdere tempo a cercare di capire perché è lento !!! Se è più veloce in Query Builder, questo è abbastanza buono per me !!

Gli sviluppatori di @Laravels: ottimo lavoro sul framework. È intuitivo, si occupa bene delle autorizzazioni, in particolare con i plug-in di fiducia e affidamento di Leroy Merlin. Potresti voler dare un'occhiata al problema delle prestazioni di Eloquent !!

Cheers! Craig

+0

Cosa intendi con Leroy Merlin? Entrust and Confide sono stati scritti da Zizaco [link] (https://github.com/Zizaco/confide) –

+0

Eloquent si trova in cima a Query Builder, analizzando i dati restituiti nelle istanze di classe.Questo sarà sempre più lento rispetto all'utilizzo di solo Query Builder. È possibile memorizzare nella cache risultati Eloquent con: "Organization :: all() -> remember (5);". – assertchris

2

Assicurarsi di eseguire un RESET QUERY CACHE per svuotare la cache di query MySQL tra un test e l'altro. Dai timestamp che hai postato sembra che tu abbia fatto prima le query di Eloquent, il che significa che probabilmente sono state memorizzate nella cache quando hai eseguito il secondo test. Ciò spiegherebbe l'enorme differenza di prestazioni, anche se sospetto che Eloquent sia un po 'più lento delle normali query di Laravel a causa del sovraccarico aggiuntivo.

2

Quando si esegue DB::table('t_organisations')->get(); recupera tutti i risultati come una matrice (o oggetti), ma non li idratare al modello. Vedere this stackoverflow answer se si desidera una spiegazione rapida.

Quando si esegue Organisation::all(); Il processo di idratazione avviene, che è il motivo per cui la richiesta richiede più tempo (si deve allocare tutti gli oggetti nella memoria e riempirli con i campi). Ci sono molti link/tut sull'ottimizzazione dell'idratazione per aiutarti a richiedere meglio il tuo database ed evitare l'idratazione degli oggetti quando non ne hai bisogno.

Problemi correlati