2015-07-27 11 views
5

mi aspetto questa chiamatamodo più veloce per trovare l'ultimo timestamp aggiornato

Model.maximum(:updated_at) 

essere più veloce di questo

Model.order(:updated_at).last.updated_at 

C'è qualcuno in grado di confermare questa affermazione? e, se è vero, spiega perché?

+0

La seconda query ha generato un errore 'ordine metodo non definito per # ' per me. – Pavan

+0

@Pavan Hai ragione, ho aggiornato la mia domanda. – Nanego

risposta

1

È possibile utilizzare il the Benchmark module per indagare facilmente, ad es .:

require 'benchmark' 

n = 50000 
Benchmark.bm do |x| 
    x.report('maximum') { n.times.do; v1; end } 
    x.report('order-pluck') { n.times do; v2; end } 
end 

def v1 
    clear_cache 
    Model.maximum(:updated_at) 
end 

def v2 
    clear_cache 
    Model.order(:updated_at).pluck(:updated_at).last 
end 

def clear_cache 
    ActiveRecord::Base.connection.query_cache.clear 
end 

per rendere la pena fare questo con n> 1 dovrete cancellare le varie cache che potrebbero essere coinvolti. Potrebbe esserci una cache nel tuo server db, separata dalla cache di ActiveRecord. Ad esempio per cancellare la cache Mysql è possibile chiamare:

`mysql mydb -e 'RESET QUERY CACHE'` 
+0

Grazie. Il modulo benchmark è di grande aiuto, anche se non spiega il perché. – Nanego

0

L'aspettativa è corretta.

Quando si chiama Model.maximum(:updated_at), si chiede al DB di restituire solo un valore singolo.

Quando si chiama Model.order(:updated_at).pluck(:updated_at).last, il database restituisce tutti i valori per la colonna updated_at nella tabella, che consuma più memoria (perché è necessario creare un grande array) e impiega più tempo.

+0

Cosa succede se seleziono solo una colonna? Model.select (: updated_at) .order (: updated_at) .last.updated_at – Nanego

+0

Penso che dipenda allora, dal fatto che ci sia un indice o questa colonna o meno, quante voci ci sono nella tua tabella. Ma in generale non dovrebbe esserci alcuna grande differenza allora. –