Optymalizacja zapytania SQL - SELECT sum("votes".vote) AS sum_vote

Używam lekko zmodyfikowanej wtyczki do głosowania vote_fu.

W jej zmodyfikowanej wersji metoda Voteable.votes_total wysyła np. takie zapytanie:

SELECT sum("votes".vote) AS sum_vote FROM "votes" WHERE (voteable_id = 2 AND voteable_type = 'RecommendedUser')

Sama metoda wygląda tak:

[code “ruby”]#vote_fu/lib/acts_as_voteable.rb

    def votes_total
      Vote.sum(:vote, :conditions => [
        "voteable_id = ? AND voteable_type = ?",
        id, self.class.name
      ])
    end[/code]

Problem leży w tym, że gdy w partialu umieszczam voteable.votes_total, to do bazy mogą zostać wysłane dziesiątki takich zapytań.

Jak temu zapobiec? W czystym SQL-u jeszcze nie pisałem żadnych wymyślnych zapytań, a :include => :votes oczywiście nie działa.

Zacznijmy od podstawowej sprawy: dlaczego uważasz, że musisz optymalizować metodę obliczającą głosy? Czy faktycznie długo trwają te zapytania? Nie ma sensu optymalizować zawczasu, stąd moje pytania. Zakładam oczywiście, że założyłeś indeks (votable_id, votable_type) - bez tego ani rusz.
Z samym zapytaniem raczej niewiele możesz już zrobić. Myślę, że kolejnym krokiem optymalizacyjnym byłoby keszowanie sumy głosów (przeliczanie tylko gdy dodawany/usuwany jest głos) i/lub keszowanie całego partiala (taka informacja jak calkowita liczba głosów nie musi być zawsze w 100% aktualna).

Indeksy są bodajże dodawane przez samą wtyczkę:

add_index :votes, ["voter_id", "voter_type"], :name => "fk_voters" add_index :votes, ["voteable_id", "voteable_type"], :name => "fk_voteables"

Chodziło mi nie tyle o optymalizację zapytania, co po prostu myślałem, że skoro używam eager loading przy asocjacjach, to może tutaj dałoby się zrobić coś podobnego (jedno zapytanie dotyczące głosów zamiast 50 czy 100 i później już wczytywanie danych z cache’u).

Ale skoro takie proste zapytanie nie obciąża zbytnio bazy, to chyba faktycznie nie muszę bać się tak bardzo o wydajność, bo jednorazowo tych zapytań nie będzie pewnie więcej niż 100.

Nigdy nie wiadomo czy nie obciąży, ale zacznij się martwić i to optymalizować jeżeli jednak tak się stanie. Czyli jednym słowem - nie stosujemy przedwczesnej optymalizacji. O to chyba chodziło radarkowy :slight_smile: