Veiktspēja ir viens no svarīgākajiem aspektiem, kas jāņem vērā, izstrādājot tīmekļa lietojumprogrammas. Analizējot, kā dati tiek saņemti no datubāzes, ir labs sākumpunkts, meklējot uzlabojumus. Šajā rakstā atradīsiet piemērus, kā uzlabot veiktspēju, izmantojot apkopojošās funkcijas un filtrējot datus datubāzes līmenī.
Dažas lietas sākumā
Šo rakstu iedvesmoja reāla problēma, ar kuru man reiz ir nācies saskarties. Tās risināšana man daudz ko iemācīja, un man tā joprojām ir kā atsauce prātā. Manuprāt, piemēri ir labs mācību materiāls, tie var daudz ko izskaidrot. Šajā rakstā vēlos dalīties ar dažiem piemēriem par Active Record vaicājumu metožu izmantošanu.
Lai neieviestu ar domēnu saistītas detaļas, piemēru ilustrēšanai izmantošu bibliotēkas lietojumprogrammas paraugu. Viss ir diezgan vienkārši, kā parādīts diagrammā zemāk. Mums ir četras tabulas: autori, grāmatas, lietotāji un nomas. Viens lietotājs var aizņemties daudzas grāmatas, un vienu grāmatu var aizņemties daudzi lietotāji, tāpēc mums ir nepieciešama savienojošā tabula, lai modelētu attiecības "daudz pret daudz". Mūsu gadījumā tā ir nomas tabula. Tajā mēs glabājam arī papildu informāciju, proti, aizņemšanās un atgriešanas datumus. Autoram var būt daudzas grāmatas, kas piešķirtas viņa vārdam. Grāmatai ir arī atribūts, kas nosaka tās žanru.
Lietotāju lasīšanas statistika
Uzdevums bija sagatavot statistiku par vienu lietotāju, lai mēs varētu pateikt, cik daudz katra žanra grāmatu ir aizņemtas. Mana pirmā doma bija iegūt visas grāmatas, kuras lietotājs ir aizņēmies, sagrupēt tās pēc žanra un pēc tam veikt kartēšanu, lai katram žanram tiktu piešķirts grāmatu skaits, nevis saraksts. Lūk, ko es izdomāju:
Lai gan šī pieeja darbojas un izskatās tīri, tā neizmanto visas iespējas, ko piedāvā Active Record vaicājuma metodes. Pateicoties tām, mēs varam filtrēt un apkopot dati datubāzes līmenī, neizmantojot neapstrādātu SQL tieši mūsu kods. Darbība db līmenī arī palielina mūsu efektivitāti.
Iepriekš minētajā piemērā mēs varam izmantot grupu metodi, nevis Ruby's group.pēc metodes. Tā piemēros GROUPBY klauzulu tSQL vaicājumā. Turklāt kartēšanas un lieluma metodi var aizstāt ar skaitīšanas agregēšanas funkciju. Beigu beigās mēs iegūstam šādu vaicājumu:
Book.joins(:rentals).where(rentals: { user: user }).group(:genre).count(:books)
Tas izskatās vēl vienkāršāk!
Citi noderīgi piemēri
Zemāk atradīsiet dažus citus pieprasīšanas metožu izmantošanas veidus, kurus, manuprāt, ir vērts zināt.
Aicinājums neaktīvajiem lietotājiem
UZDEVUMS: Uzdevums: Izfiltrējiet lietotājus, kuri nekad nav aizņēmušies grāmatu vai ir to darījuši vairāk nekā pirms gada.
Mēs varētu iegūt visus lietotājus, iekļaujot saistītās īres maksas, un pēc tam tos filtrēt, izmantojot atlases metodi.
Lietotājs.includes(:noma).select do |lietotājs|
user.nomaals.empty? ||| user.rentals.none? { || noma| noma.start_date >= Date.today - 1.year }
end
Bet, protams, nav nepieciešams visu ņemt līdzi. Izmantojot vaicājuma metodes, mēs to varam izfiltrēt db līmenī. Vispirms atlasīsim lietotājus, kuri pēdējā gada laikā ir aizņēmušies dažas grāmatas, un pēc tam izslēgsim tos no galīgās atlases.
Lietojot left_joins (un vispār ārējos savienojumus), ir svarīgi atcerēties vienu lietu. Ja kreisajā tabulā (šeit: autori) ir ieraksti, kuriem nav atbilstošu ierakstu labajā tabulā (šeit: grāmatas), tad rezultātā labās tabulas kolonnas tiks aizpildītas ar nulles vērtībām.
Tā kā mums ir vajadzīgi arī autori, kuriem sistēmā ir piešķirta viena grāmata, ir jāveic vēl dažas darbības. Mums būs jāveic grupēšana, skaitīšana un nosacījuma pievienošana. Lūk, kā to visu salikt kopā:
Nosacījums ir aiz apkopošanas funkcijas, tāpēc tā norādīšanai ir jāizmanto HAVING klauzula, nevis WHERE klauzula.
Domājot par lietojumprogrammas veiktspēju, ir vērts pārbaudīt Active Record vaicājumu metodes. Tās var vienkāršot jūsu kodu un padarīt to ātrāku. Es ceru, ka kopīgie piemēri palīdzēs jums izpētīt iespējas, ko piedāvā vaicājumu metodes.