Ytelse er et av de viktigste aspektene å ta hensyn til når man utvikler webapplikasjoner. Å analysere hvordan data hentes fra en database, er et godt utgangspunkt for å finne forbedringer. I denne artikkelen finner du eksempler på hvordan du kan forbedre ytelsen ved å bruke aggregerte funksjoner og filtrere data på databasenivå.
Litt kontekst til å begynne med
Denne artikkelen er inspirert av et reelt problem jeg en gang fikk i oppgave å løse. Jeg lærte mye av det, og jeg har det fortsatt som en referanse i tankene mine. Jeg synes eksempler er en god læringsressurs, de kan avklare mye. I denne artikkelen vil jeg gi deg noen eksempler på hvordan du kan bruke spørringsmetodene i Active Record.
For ikke å introdusere domenespesifikke detaljer, vil jeg bruke en eksempelapplikasjon for et bibliotek for å illustrere eksempler. Det hele er ganske enkelt, som vist i diagrammet nedenfor. Vi har fire tabeller: forfattere, bøker, brukere og utleie. Én bruker kan låne mange bøker, og én bok kan lånes av mange brukere, så vi trenger en sammenføyningstabell for å modellere mange-til-mange-relasjoner. I vårt tilfelle er det utleietabellen. Vi lagrer også noe tilleggsinformasjon der, nemlig datoene for lån og tilbakelevering. En forfatter kan ha mange bøker knyttet til navnet sitt. En bok har også et attributt som definerer sjangeren.
Statistikk over brukerlesing
Oppgaven var å utarbeide statistikk for en enkelt bruker, slik at vi kunne se hvor mange bøker fra hver sjanger som var lånt. Min første tanke var å hente alle bøkene som har blitt lånt av brukeren, gruppere dem etter sjanger og deretter gjøre mappingen, slik at hver sjanger får et antall bøker tildelt i stedet for en liste. Her er hva jeg kom frem til:
Selv om denne tilnærmingen fungerer og ser ryddig ut, utnytter den ikke alle mulighetene som spørringsmetodene i Active Record tilbyr. Takket være dem kan vi filtrere og aggregere data på databasenivå uten å bruke rå SQL direkte i kode. Å operere på db-nivå øker også effektiviteten vår.
I eksempelet ovenfor kan vi bruke group-metoden i stedet for Rubys groupetter metode. Den vil bruke GROUPBY-klausulen til tSQL-spørringen. Videre kan kartleggings- og størrelsesmetoden erstattes med en telleaggregeringsfunksjon. Til slutt sitter vi igjen med en spørring som ser slik ut:
Book.joins(:rentals).where(rentals: { user: user }).group(:genre).count(:books)
Det ser enda enklere ut!
Andre nyttige eksempler
Nedenfor finner du noen andre måter å bruke spørringsmetodene på som jeg synes er verdt å kjenne til.
Invitasjon til inaktive brukere
OPPGAVE: Filtrer brukere som aldri har lånt en bok eller gjorde det for mer enn ett år siden.
Vi kan hente alle brukere ved å inkludere de tilknyttede leieobjektene og deretter filtrere dem ved hjelp av select-metoden.
User.includes(:rentals).select do |user|
user.rentals.empty? || bruker.utleie.ingen? { |rental| rental.start_date >= Date.today - 1.year }
end
Men det er selvfølgelig ikke nødvendig å hente alt. Ved å bruke spørringsmetodene kan vi filtrere det ut på db-nivå. La oss først velge ut brukere som har lånt noen bøker det siste året, og deretter ekskludere dem fra det endelige utvalget.
OPPGAVE: Skaff forfattere med én eller null lånte bøker
Det er superenkelt å gjøre det med select-metoden, men igjen - det er ikke nødvendig å operere på et så stort sett med data, ettersom db-en kan filtrere det for oss:
Det er viktig å huske én ting når du bruker left_joins (og outer joins generelt). Hvis det finnes poster i den venstre tabellen (her: forfattere) som ikke har tilsvarende poster i den høyre tabellen (her: bøker), vil kolonnene i den høyre tabellen bli fylt ut med nullverdier.
Siden vi også trenger forfattere med én bok tildelt i systemet, er det noen flere operasjoner som må gjøres. Vi må gruppere, telle og legge til en betingelse. Slik setter vi det hele sammen:
Betingelsen kommer etter aggregeringsfunksjonen, så vi må bruke HAVING-klausulen i stedet for WHERE-klausulen for å spesifisere den.
Active Record-spørringsmetodene er verdt å sjekke når du tenker på applikasjonens ytelse. De kan forenkle koden din og få den til å fungere raskere. Jeg håper at eksemplene i denne artikkelen vil hjelpe deg med å utforske mulighetene spørringsmetodene har å by på.