15 Jan
matte

matte il 15 January 2006 parla di Rails Snippet

Velocizza le tue applicazioni Rails!

Molto spesso il Modulo ActiveRecord e il framework Ruby on Rails vengono considerati lazy (in italiano pigri). In altre parole questo significa che il programmatore, invece di ottimizzare le richieste al database (effettuando un numero limitato di query), utilizza i metodi delle associazioni e relazioni tra oggetti che mette a disposizione il Rails. Questo può andar bene fino a quando un’applicazione web è di piccole dimensioni, ma nel momento in cui questa cresce e il numero di accessi sono svariati, possiamo incappare in un rallentamento se non in un blocco dell’applicazione e ancor peggio del server.

Vediamo un esempio per entrare nel vivo della questione. Supponiamo di dover sviluppare un catalogo prodotti in cui esistono delle categorie principali e delle sottocategorie:

Notebook:

  • Acer
  • Apple
  • HP
  • Sony

Monitor:

  • Apple
  • Samsung
  • Sony

dove Notebook e Monitor fanno parte della tabella Categories mentre i produttori di quella Companies

Per visualizzare la lista precedente sono necessarie le seguenti righe di codice (caso Lazy)

    1 <% Category.find(:all).collect do |cat| %>
    2     <p><%= cat.name %></p>
    3     <ul>
    4         <% cat.companies.collect do |comp| %>
    5         <li><%= comp.name %></li>
    6         <% end %>
    7     </ul>
    8 <% end %>

In questo caso viene eseguita una query alla riga 1 e n alla riga 4 (n = numero delle categorie). Nel caso in cui le categorie siano 100 vengono effettuate 101 query da parte del database.

Utilizzando l’eager loading (metodo con cui recuperiamo oggetti (collegati tra loro da associazioni( dal database con una singola query) otteniamo gli stessi dati:

    1 <% Category.find(:all, :include => [:companies]).collect do |cat| %>
    2     <p><%= cat.name %></p>
    3     <ul>
    4         <% cat.companies.collect do |comp| %>
    5             <li><%= comp.name %></li>
    6         <% end %>
    7     </ul>
    8 <% end %>

Inserendo

    1 :include => [:companies]

all’interno del metodo find carichiamo all’interno della lista delle categorie anche le aziende che ne fanno parte evitanto di richiederle ogni volta al database. Questo procedimento è chiamato Eager Loading. Passiamo quindi dall’esecuzione di n + 1 query all’esecuzione di 1 sola.

Scrivi un commento