Optymalizacja zapytań

Witam,

co jest optymalne:

[code=“Ruby”]#Controller:

@article = Article.find(1)

#View
<%= @article.id %>
<%= @article.user.nickname %>[/code]
czy

[code=“Ruby”]#Controller:
@article = Article.find(:first,:select => ‘articles.id,article.title,users.nickname,users.id as user_id’,
:joins => ‘LEFT OUTER JOIN users ON users.id = article.user_id’ )

#View
<%= @article.id %>
<%= @article.nickname %>[/code]
Moje pytanie opieram na artykule http://fortytwo.gr/blog/18/9-Essential-Rails-Tips i zawartych w nim komentarzy

Pozdrawiam

Podejrzewam, że to drugie może być trochę szybsze, aczkolwiek nie polecam wrzucania takich konstrukcji przy developmencie. To chyba podchodzi pod przedwczesną optymalizację. Trzeba zwracać uwagę na szybkość, ale moim zdaniem zapytania powinno się optymalizować dopiero, kiedy wydajność można sprawdzić w praktyce na działającej aplikacji.

I puszczać testy wydajnościowe po każdej zmianie optymalizacyjnej! Bo to, że komuś się wydaje, że to przyśpieszy nie daje pewności, że tak naprawdę będzie - w skrajnych przypadkach można nawet spowolnić.

Bzdury jakieś, gość opisuje te rozwiązania jako domyślne dla AR a AR powstało właśnie dla prostoty i wygody użycia i żeby pozbyć się listowania wszystkich kolumn w każdym zapytaniu. Optymalizacja zanim wystąpi problem to źródło wszelkiego zła, dlaczego chcesz to robić ? Na pewno optymalne nie jest wsadzanie :select w każdego find’a, szybkość zapytań zależy od struktury tabel, indeksów itp. Sprawdź logi, zobacz jakie zapytania generuje AR, optymalizuj wolne zapytania jak jest z nimi problem a nie zawczasu. Nie zapomnij o indeksach na kluczach obcych, poza tym :include może być równie szybkie jak :select, trzeba tylko uważać żeby nie ładować do pamięci kilka tysięcy rekordów ( co często się zdarza początkującym którzy bezmyślnie używają :include).

Wiem że nie robiłem testów wydajnościowych ale na logikę w pierwszym przypadku idzie jedno zapytanie - pobiera dane których nie używam i drugie zapytanie w widoku kiedy dostaje się do danych usera, gdzie również pobiera wszystkie dane. W drugim wypadku idzie jedno zapytanie a dane pobierane te które potrzebuję. Stąd moje pytanie… przy dużym obciążeniu może to chyba robić różnicę?

Jak dla mnie takie coś :select jest brzydkie. Czy taki obiekt Article będzie? Nie będziesz miał accessorów dla których nie dopiszesz select. Ja unikam opcji select jak mogę, dla mnie zło. :slight_smile:
Lepiej skoncentrować się na indeksach itp.

No widzę, że :select bee, ale kusi, mam nadzieję, że będziecie robić jakieś testy, jakie macie na dzisiaj zalecenia dla użycia :select?

JJ, czy jesteś pewien, że to 1 zapytanie jest kluczowym miejscem do optymalizacji w Twojej aplikacji? Podejrzewam, że dla tego 1 zapytania szkoda w ogóle się rozwodzić co jest szybsze. Używanie opcji :select to jak dla mnie wyjście poza opiekuńcze ramiona AR i praca na własne ryzyko. Równie dobrze możesz użyć ActiveRecord::Base.select_one(“select …”), tylko czy ma to sens? Zanim odpowiesz sobie na pytanie co jest szybsze wpierw sprawdź co w Twojej aplikacji jest najwolniejsze…

W railsach 2.1 ten include nie jest taki straszny, bo nie tworzy jednego wielkiego zapytania z wszystkimi polami tylko rozbija to na kilka zapytań w zależności od tego ile modeli bierze w tym udział. Tylko nie można dawać żadnych warunków, bo wtedy znowu generuje jedno wielkie zapytanie.

Ok, a co z użyciem np funkcji MySql’owych? Jakby chciał na jakimś polu wykonać LEFT lub instrukcje warunkowe?

No wtedy jest generowane znowu jedno zapytanie.