12

Se si dispone di un'app Rail con molti modelli associati complessi, quali tecniche si impiegano per ridurre le query del database?Tecniche per ridurre le query del database in un'app Rails

In effetti, estenderò ulteriormente questa domanda e chiedo, quali considerano "troppe" query per qualsiasi pagina?

Ho una pagina che prevedo che finirà per colpire il database circa 20 volte ogni caricamento della pagina. Queste preoccupazioni sono ma non so se dovrebbe interessarmi o cosa posso fare per ridurre il carico?

risposta

14

Partenza: bullet

E 'un ottimo modo per identificare n + 1 query ed offre suggerimenti per ridurre al minimo esso.

Fa rallentare la modalità di sviluppo, quindi assicurati di disabilitarla quando non stai ottimizzando le prestazioni.

Mentre noi siamo, checkout anche: rails_indexes

Un modo semplice per identificare quali indici vostra applicazione poteva mancare.

Accordatura felice.

+0

Come si riduce effettivamente il caricamento del database? Per memoria cache? –

-1

È davvero difficile stimare un limite per le query. Questo è legato al concetto/design della tua applicazione.

Se non si deve ricaricare l'intera pagina, suggerisco di considerare javascript (o rjs) per aggiornare solo i dati necessari. Questo dovrebbe essere anche un miglioramento dell'interfaccia utente, i tuoi utenti lo adoreranno!

Controllare l'SQL generato dalle query di ActiveRecord. Assicurati che tutto sia come previsto.

Prendere in considerazione la denormalizzazione del db per migliorare le prestazioni. (attenzione)

Questo è ciò che vedo dal "codice".

10

Una pratica comune è l'uso giudizioso dell'opzione =>: opzione di associazione.

Per esempio su un controller si potrebbe fare:

def show 
    @items = Item.find(:all) 
end 

... e la vista spettacolo sarebbe fare qualcosa di simile:

<% @items.each |item| %> 
    <%= item.product.title %> 
<% end %> 

Questo creerà una query per ogni chiamata al prodotto. Ma se si dichiara l'associazione incluso nel seguente modo, si ottiene associazioni avidamente-caricati in una query:

def show 
    @items = Item.find(:all, :include => :product) 
end 

Come sempre, controllare la console per i tempi di query e così via.

0

Sto utilizzando: join e: selezionare le opzioni se è necessario solo per visualizzare i dati. Ho trovato molto utile named_scope per definire tutti i possibili: join e uno: select_columns named_scope.Esempio

class Activity < ActiveRecord::Base 
     belongs_to :event 
     belongs_to :html_template 
     has_many :participants 

     named_scope :join_event, :joins => :event 
     named_scope :join_owner, :joins => {:event => :owner} 
     named_scope :left_join_html_template, 
     :joins => "LEFT JOIN html_templates ON html_templates.id = activities.html_template_id" 
     named_scope :select_columns, lambda { |columns| {:select => columns}} 
     named_scope :order, lambda{ |order| {:order => order}} 
end 

Così ora si può facilmente creare query come questa:

columns = "activities.*,events.title,events.owner_id,owners.full_name as owner_name" 
@activities = Activity.join_event.join_owner.order("date_from ASC").select_columns(columns) 

Ritengo che questo non è il modo migliore e più sicuro, ma nel mio caso è davvero minify numero di query che esegue per ogni richiesta e non ci sono ancora errori relativi ad alcune query generate errate.

Problemi correlati