16

Występuję w konkretnej sytuacji, w której renderowany json wygenerowany przez ActiveModel :: Serializer jest nadzwyczajnie wolny (około 6-8 sekund). Jak mogę poprawić szybkość tego renderowania? Oto kod.Aktywacja aktywnego modelu Serializer - Zwiększenie wydajności renderingu

Modele:

class Comment < ActiveRecord::Base 
    has_many :children_comments, 
      class_name: 'Comment', 
      foreign_key: 'parent_comment_id' 

    belongs_to :user 
    belongs_to :parent_comment, 
      class_name: 'Comment', 
      foreign_key: 'parent_comment_id' 
end 

Serializers:

class CommentSerializer < ActiveModel::Serializer 
    include ActionView::Helpers::DateHelper 

    attributes :id, :message, :created_at_in_words, 
      :created_at, :parent_comment_id 
    belongs_to :user 
    has_many :children_comments 

    def created_at_in_words 
    time_ago_in_words(object.created_at) + ' ago' 
    end 

    def children_comments 
    object.children_comments.map do |comment| 
     CommentSerializer.new(comment).as_json 
    end 
    end 
end 

class UserSerializer < ActiveModel::Serializer 
    attributes :id, :name, :avatar_url 

    def avatar_url 
    object.avatar.url 
    end 
end 

W moim kontroler mam

parent_comments = Comment.where(parent_comment_id: nil) 

    render status: :ok, 
     json: parent_comments, 
     each_serializer: CommentSerializer, 
     key_transform: :camel_lower 

Oto mój dziennik częściowe wyjście kiedy nawiązać połączenie z serwerem. Jak widzisz, model Active Serializer zajmuje około 20 ms, aby wykonać każde wywołanie zapytania.

Started GET "/comments?lesson_id=420" for ::1 at 2016-09-01 11:09:14 -0400 
Processing by Api::CommentsController#index as HTML 
    Parameters: {"lesson_id"=>"420"} 
    User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["id", 102]] 
    Lesson Load (0.5ms) SELECT "lessons".* FROM "lessons" WHERE "lessons"."id" = $1 ORDER BY position ASC LIMIT 1 [["id", 420]] 
    Comment Load (53.0ms) SELECT "comments".* FROM "comments" WHERE "comments"."commentable_id" = $1 AND "comments"."commentable_type" = $2 AND "comments"."parent_comment_id" IS NULL [["commentable_id", 420], ["commentable_type", "Lesson"]] 
[active_model_serializers] User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (24.6ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41401]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (20.3ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41402]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (22.7ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41403]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (21.6ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41404]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.4ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41405]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (20.5ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41406]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (20.4ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41407]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (20.3ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41408]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.6ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41409]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.7ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41410]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.2ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41411]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.4ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41412]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.8ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41413]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (23.5ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41414]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41415]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.4ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41416]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (23.7ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41417]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.5ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41418]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.6ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41419]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.7ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41420]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.4ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41421]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.9ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41422]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.6ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41423]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (20.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41424]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.8ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41425]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.7ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41426]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.2ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41427]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.6ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41428]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.6ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41429]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.6ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41430]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.9ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41431]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41432]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.3ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41433]] 
[active_model_serializers] CACHE (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (21.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41434]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.8ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41435]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (21.5ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41436]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.4ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41437]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.8ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41438]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (22.9ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41439]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.7ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41440]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.4ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41441]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.9ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41442]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.8ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41443]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.7ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41444]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.2ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41445]] 
[active_model_serializers] CACHE (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.7ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41446]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.5ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41447]] 
[active_model_serializers] CACHE (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.5ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41448]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41449]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.0ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41450]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.2ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41451]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.3ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41452]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.2ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41453]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.0ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41454]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (22.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41455]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (22.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41456]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.7ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41457]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41458]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.2ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41459]] 
[active_model_serializers] CACHE (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.5ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41460]] 
[active_model_serializers] CACHE (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (20.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41461]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41462]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.6ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41463]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41464]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (20.3ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41465]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.6ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41466]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.8ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41467]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.5ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41468]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.3ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41469]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.7ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41470]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.0ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41471]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (20.4ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41472]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.4ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41473]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.0ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41474]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.3ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41475]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.6ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41476]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (19.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41477]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41478]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.8ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41479]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (20.4ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41480]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.2ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41534]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.3ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41535]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.6ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41536]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.8ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41537]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (18.3ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 41538]] 
[active_model_serializers] Rendered ActiveModel::Serializer::CollectionSerializer with ActiveModelSerializers::Adapter::Json (3895.33ms) 
Completed 200 OK in 4007ms (Views: 1222.1ms | ActiveRecord: 2743.8ms) 

Z odpowiedzią Michała, tutaj jest mała próbka z dziennika.

Started GET "/comments?lesson_id=370" for ::1 at 2016-09-02 17:13:06 -0400 
Processing by Api::CommentsController#index as HTML 
    Parameters: {"lesson_id"=>"370"} 
    User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["id", 102]] 
    Lesson Load (0.4ms) SELECT "lessons".* FROM "lessons" WHERE "lessons"."id" = $1 ORDER BY position ASC LIMIT 1 [["id", 370]] 
    Comment Load (23.0ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" IS NULL AND "comments"."commentable_type" = 'Lesson' AND "comments"."commentable_id" = 370 
    User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."id" IN (102) 
    Comment Load (25.7ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" IN (38641, 38687, 38733) 
    CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" IN (102) 
[active_model_serializers] Comment Load (20.3ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 38642]] 
[active_model_serializers] User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (20.7ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 38643]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 
[active_model_serializers] Comment Load (30.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."parent_comment_id" = $1 [["parent_comment_id", 38644]] 
[active_model_serializers] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 102]] 

Moja teoria jest taka. Jestem przekonany, że serializacja children_comments powoduje większość problemów z wydajnością. Ponieważ do każdego komentarza muszę wywoływać komendy children_comments, powoduje to efekt kaskadowy. Zastanawiam się, czy mogę przepisać kod w taki sposób, aby poprawić wydajność.

+0

Czy używasz klejnotu oj? – DVG

+0

Tak, klejnot ojczyzny wykazuje niewielką różnicę w wydajności. – jason328

+0

Czy próbowałeś to profilować? Z ruby-prof lub stackprof? Pokaże, która część jest rzeczywiście wolna. –

Odpowiedz

5

zmienić zapytanie ActiveRecord do tego

parent_comments = Comment.where(parent_comment_id: nil).includes(:user, children_comments: :user) 

Będzie pozbyć N + 1 zapytaniami.

+0

Niestety, nie poprawiło to czasu. Czas ładowania komentarzy był mniej więcej taki sam. – jason328

+0

@ jason328 A jak teraz wygląda wyjście logu? –

+0

opublikowane w pytaniu. – jason328

3

Występuje problem z typem zapytania n + 1. Niestety, nie pomagam ci tutaj includes, ponieważ pomaga ci to tylko na jednym poziomie stowarzyszenia - unika oddzielnych pobrań dzieci z komentarzem na najwyższym poziomie, ale nie ma wielkich dzieci i prawnuków.

Prawdopodobnie można zoptymalizować wyszukiwanie użytkowników, zachowując własną pamięć podręczną identyfikatora użytkownika dla obiektów użytkownika (pamięć podręczna szyn buforuje nieprzetworzone dane, ale będzie ponownie instalować obiekty w kółko), ale aby uczynić to znacznie szybszym, czego potrzebujesz aby zmienić sposób ładowania komentarzy.

Jeśli korzystasz z bazy danych, która obsługuje tę funkcję (np. Postgresql), wtedy zapytania rekurencyjne są opcją (zobacz przykładowy przykład: https://hashrocket.com/blog/posts/recursive-sql-in-activerecord). Nie znam tej skali, gdy drzewo staje się coraz głębsze.

Jeśli zapytania rekurencyjne nie są opcją, istnieje kilka podejść, które wymagają zmiany tego, co przechowujesz.

Jednym z nich jest zmaterializowana ścieżka patten. Na przykład powiedzmy, że komentarz roota ma id 1, dziecko ma id 101 i jedno z jego dzieci ma id 426. Ta ostatnia ścieżka komentarza to 1/101/426. Wszystkie jego rodzeństwo ma ścieżki zaczynające się od 1/101/. Oznacza to, że możesz używać podobnych zapytań (z symbolami wieloznacznymi na końcu), aby szybko znaleźć poddrzewa. Klejnot ten implementuje to. Jeśli komentarze zostaną przeniesione, musisz przepisać ścieżki wszystkich komentarzy dla dzieci (i wielkich dzieci itp.), Ale może to nie być istotne dla twojego przypadku użycia. Uważam, że bardzo głębokie drzewa są problematyczne.

Kolejny to zagnieżdżony wzorzec zestawu. Podstawową ideą jest to, że węzeł nadrzędny przechowuje minimalny i maksymalny identyfikator wszystkich swoich dzieci i dzieci ich dzieci itd. Pozwala to na pobieranie wszystkich tych dzieci za jednym zamachem.Z drugiej strony wkładki i aktualizacje wymagają przepisywania wielu danych (w większym stopniu niż w przypadku zmaterializowanej ścieżki). Istnieją różne klejnoty, które realizują to przez lata (obecny wydaje się być awesome_nested_set).

Warto również sprawdzić, czy masz odpowiednie indeksy do obsługi zapytań - chyba że naprawdę jest dużo komentarzy z danym rodzicem, 20-30ms wydaje się dość długi czas na jedno zapytanie.

+0

Podałeś najbardziej wyczerpującą odpowiedź z kilkoma możliwymi rozwiązaniami. W tym celu dam ci kredyt. Dzięki za wyczerpującą odpowiedź. – jason328