2014-03-25 161 views
0

使用Rails 4和Ruby 1.9.3。 我在usuarios中有这个视图#show我正在渲染。控制器需要大量的数据,但我设法减少了eager_load的查询,从300ms奇数到44ms。为什么Rails渲染视图太慢?

我的问题是数据库调用没问题,但视图花费接近30秒来渲染。

我已经确定我从控制器变量中获得了所有的东西。

编辑:我从控制器

这是控制器的方法,采用eager_loading

​​

这里添加的查询本身就是我的日志

Started GET "/" for 127.0.0.1 at 2014-03-25 12:55:39 +0100 
    Usuario Load (1.4ms) SELECT "usuarios".* FROM "usuarios" WHERE "usuarios"."id" = 12 ORDER BY "usuarios"."id" ASC LIMIT 1 
Processing by UsuariosController#show as HTML 
    Notification Load (1.2ms) SELECT "notifications".* FROM "notifications" INNER JOIN "textos" ON "textos"."id" = "notifications"."text" WHERE (textos.usuario_id = 12 AND notifications.user_related != 12) ORDER BY "notifications"."id" DESC LIMIT 10 
    SQL (1.2ms) SELECT "usuarios"."id" AS t0_r0, "usuarios"."email" AS t0_r1, "usuarios"."encrypted_password" AS t0_r2, "usuarios"."reset_password_token" AS t0_r3, "usuarios"."reset_password_sent_at" AS t0_r4, "usuarios"."remember_created_at" AS t0_r5, "usuarios"."sign_in_count" AS t0_r6, "usuarios"."current_sign_in_at" AS t0_r7, "usuarios"."last_sign_in_at" AS t0_r8, "usuarios"."current_sign_in_ip" AS t0_r9, "usuarios"."last_sign_in_ip" AS t0_r10, "usuarios"."created_at" AS t0_r11, "usuarios"."updated_at" AS t0_r12, "usuarios"."nombre" AS t0_r13, "usuarios"."fecha_nac" AS t0_r14, "usuarios"."country_id" AS t0_r15, "usuarios"."is_admin" AS t0_r16, "usuarios"."publish_fbviews" AS t0_r17, "usuarios"."accept_terms" AS t0_r18, "profiles"."id" AS t1_r0, "profiles"."usuario_id" AS t1_r1, "profiles"."quote" AS t1_r2, "profiles"."quote_author" AS t1_r3, "profiles"."fb_account" AS t1_r4, "profiles"."twt_account" AS t1_r5, "profiles"."gpls_account" AS t1_r6, "profiles"."biografia" AS t1_r7, "profiles"."created_at" AS t1_r8, "profiles"."updated_at" AS t1_r9, "profiles"."hide_email" AS t1_r10, "profiles"."pic_file_name" AS t1_r11, "profiles"."pic_content_type" AS t1_r12, "profiles"."pic_file_size" AS t1_r13, "profiles"."pic_updated_at" AS t1_r14 FROM "usuarios" LEFT OUTER JOIN "profiles" ON "profiles"."usuario_id" = "usuarios"."id" WHERE "usuarios"."id" = $1 LIMIT 1 [["id", 12]] 
USER CARGADO 
    Country Load (0.7ms) SELECT "countries".* FROM "countries" WHERE "countries"."id" = $1 LIMIT 1 [["id", 246]] 
TEXTOS CARGADOS 
    Rendered usuarios/_main_frame.html.erb (12082.9ms) 
    (1.6ms) SELECT COUNT(DISTINCT "textos"."id") FROM "textos" LEFT OUTER JOIN "likes" ON "likes"."texto_id" = "textos"."id" LEFT OUTER JOIN "text_medals_textos" ON "text_medals_textos"."texto_id" = "textos"."id" LEFT OUTER JOIN "text_medals" ON "text_medals"."id" = "text_medals_textos"."text_medal_id" LEFT OUTER JOIN "tags_textos" ON "tags_textos"."texto_id" = "textos"."id" LEFT OUTER JOIN "tags" ON "tags"."id" = "tags_textos"."tag_id" WHERE "textos"."usuario_id" = 12 
    SQL (1.9ms) SELECT DISTINCT "textos".id, textos.created_at AS alias_0 FROM "textos" LEFT OUTER JOIN "likes" ON "likes"."texto_id" = "textos"."id" LEFT OUTER JOIN "text_medals_textos" ON "text_medals_textos"."texto_id" = "textos"."id" LEFT OUTER JOIN "text_medals" ON "text_medals"."id" = "text_medals_textos"."text_medal_id" LEFT OUTER JOIN "tags_textos" ON "tags_textos"."texto_id" = "textos"."id" LEFT OUTER JOIN "tags" ON "tags"."id" = "tags_textos"."tag_id" WHERE "textos"."usuario_id" = 12 ORDER BY textos.created_at DESC LIMIT 6 OFFSET 0 
    SQL (5.6ms) SELECT "textos"."id" AS t0_r0, "textos"."usuario_id" AS t0_r1, "textos"."titulo" AS t0_r2, "textos"."contenido" AS t0_r3, "textos"."idioma" AS t0_r4, "textos"."created_at" AS t0_r5, "textos"."updated_at" AS t0_r6, "textos"."is_borrador" AS t0_r7, "textos"."is_on_contest" AS t0_r8, "textos"."portada_file_name" AS t0_r9, "textos"."portada_content_type" AS t0_r10, "textos"."portada_file_size" AS t0_r11, "textos"."portada_updated_at" AS t0_r12, "textos"."contest_id" AS t0_r13, "textos"."views" AS t0_r14, "textos"."has_draft" AS t0_r15, "textos"."license_type" AS t0_r16, "likes"."id" AS t1_r0, "likes"."usuario_id" AS t1_r1, "likes"."texto_id" AS t1_r2, "likes"."created_at" AS t1_r3, "likes"."updated_at" AS t1_r4, "text_medals"."id" AS t2_r0, "text_medals"."name" AS t2_r1, "text_medals"."slogan" AS t2_r2, "text_medals"."created_at" AS t2_r3, "text_medals"."updated_at" AS t2_r4, "text_medals"."image_file_name" AS t2_r5, "text_medals"."image_content_type" AS t2_r6, "text_medals"."image_file_size" AS t2_r7, "text_medals"."image_updated_at" AS t2_r8, "tags"."id" AS t3_r0, "tags"."nombre" AS t3_r1, "tags"."created_at" AS t3_r2, "tags"."updated_at" AS t3_r3 FROM "textos" LEFT OUTER JOIN "likes" ON "likes"."texto_id" = "textos"."id" LEFT OUTER JOIN "text_medals_textos" ON "text_medals_textos"."texto_id" = "textos"."id" LEFT OUTER JOIN "text_medals" ON "text_medals"."id" = "text_medals_textos"."text_medal_id" LEFT OUTER JOIN "tags_textos" ON "tags_textos"."texto_id" = "textos"."id" LEFT OUTER JOIN "tags" ON "tags"."id" = "tags_textos"."tag_id" WHERE "textos"."usuario_id" = 12 AND "textos"."id" IN (75, 74, 73, 70, 69, 68) ORDER BY textos.created_at DESC 
    CACHE (0.0ms) SELECT COUNT(DISTINCT "textos"."id") FROM "textos" LEFT OUTER JOIN "likes" ON "likes"."texto_id" = "textos"."id" LEFT OUTER JOIN "text_medals_textos" ON "text_medals_textos"."texto_id" = "textos"."id" LEFT OUTER JOIN "text_medals" ON "text_medals"."id" = "text_medals_textos"."text_medal_id" LEFT OUTER JOIN "tags_textos" ON "tags_textos"."texto_id" = "textos"."id" LEFT OUTER JOIN "tags" ON "tags"."id" = "tags_textos"."tag_id" WHERE "textos"."usuario_id" = 12 
    Usuario Load (0.8ms) SELECT "usuarios".* FROM "usuarios" WHERE "usuarios"."id" = $1 ORDER BY "usuarios"."id" ASC LIMIT 1 [["id", 12]] 
    Profile Load (0.7ms) SELECT "profiles".* FROM "profiles" WHERE "profiles"."usuario_id" = $1 ORDER BY "profiles"."id" ASC LIMIT 1 [["usuario_id", 12]] 
    CACHE (0.1ms) SELECT "usuarios".* FROM "usuarios" WHERE "usuarios"."id" = $1 ORDER BY "usuarios"."id" ASC LIMIT 1 [["id", 12]] 
    CACHE (0.0ms) SELECT "profiles".* FROM "profiles" WHERE "profiles"."usuario_id" = $1 ORDER BY "profiles"."id" ASC LIMIT 1 [["usuario_id", 12]] 
    CACHE (0.1ms) SELECT "usuarios".* FROM "usuarios" WHERE "usuarios"."id" = $1 ORDER BY "usuarios"."id" ASC LIMIT 1 [["id", 12]] 
    CACHE (0.0ms) SELECT "profiles".* FROM "profiles" WHERE "profiles"."usuario_id" = $1 ORDER BY "profiles"."id" ASC LIMIT 1 [["usuario_id", 12]] 
    CACHE (0.1ms) SELECT "usuarios".* FROM "usuarios" WHERE "usuarios"."id" = $1 ORDER BY "usuarios"."id" ASC LIMIT 1 [["id", 12]] 
    CACHE (0.1ms) SELECT "profiles".* FROM "profiles" WHERE "profiles"."usuario_id" = $1 ORDER BY "profiles"."id" ASC LIMIT 1 [["usuario_id", 12]] 
    CACHE (0.0ms) SELECT "usuarios".* FROM "usuarios" WHERE "usuarios"."id" = $1 ORDER BY "usuarios"."id" ASC LIMIT 1 [["id", 12]] 
    CACHE (0.0ms) SELECT "profiles".* FROM "profiles" WHERE "profiles"."usuario_id" = $1 ORDER BY "profiles"."id" ASC LIMIT 1 [["usuario_id", 12]] 
    CACHE (0.1ms) SELECT "usuarios".* FROM "usuarios" WHERE "usuarios"."id" = $1 ORDER BY "usuarios"."id" ASC LIMIT 1 [["id", 12]] 
    CACHE (0.1ms) SELECT "profiles".* FROM "profiles" WHERE "profiles"."usuario_id" = $1 ORDER BY "profiles"."id" ASC LIMIT 1 [["usuario_id", 12]] 
    Rendered usuarios/_user_texts.html.erb (16760.5ms) 
    Rendered usuarios/show.html.erb within layouts/application (28889.5ms) 
Completed 200 OK in 29246ms (Views: 28898.8ms | ActiveRecord: 44.1ms) 

,你可以看,意见需要年龄渲染。 这是“_user_texts”的一部分。编辑:编辑:我正在使用分页。特别是will_paginate的宝石。当我到达页面底部时,有一个按钮用于获取更多结果。

有人能告诉我怎样才能让它更快?这让我疯狂。 谢谢!

+1

它可能与[此载波问题](https://github.com/carrierwaveuploader/carrierwave/issues/1218)有关。你可以尝试没有图像,看看它是否恢复正常?可能值得与Github上的维护人员联系,以便他们可以重新解决问题(它看起来不像它曾经修复过)。 –

+0

'@ textos'变量有多少条记录? 'texto.tags'平均有多少条记录?我建议删除部分的'usuarios/_user_texts.html.erb',直到找到最慢的部分。 – Magnuss

+0

@ZachKemp我正在使用回形针。 – Sebastialonso

回答

0

解决。在子弹宝石的帮助下,我重新描述了我渴望加载的方式。

事实证明,所做的一切在实践中都做得很好。问题是我的合作伙伴在Dropbox中存储回形针的图像。 Dropbox很可能不是为这种请求而制作的,所以延迟是因为这个原因。我们将转向亚马逊的S3。

对于未来的读者:被建议!并检查你在哪里存储图像。

感谢大家!

1

我会基准你的查询,对我来说似乎很重。我认为重点应放在提高sql查询的性能上。我不知道确切的内容,但是我怀疑你在单个查询中需要这么多的智能。

例如,您可以在表格中添加索引以提高性能。您还应该考虑您真正需要的属性并使用select来定义它们。查询中的列数减少会产生更快的结果。

最后,你正在做很多连接。好像你几乎加入了你的所有模型。左连接非常缓慢,因为您会浏览所有记录。如果你真的需要所有这些连接,如果你可以将一些左连接变成内连接,那将是非常好的。这将意味着巨大的改进,因为您必须仅检查相关记录。

+0

感谢您的见解。我会阅读内部连接,听起来不错。 – Sebastialonso

+1

如果您在开始的帖子中显示您的查询,这将非常有用。现在我们看到了所有的sql输出,这对人们来说不太适合阅读。特别是在手机上。 :) –

+0

你完全正确。我现在将添加它。 – Sebastialonso

1

查询实际上并没有运行,直到您在视图中调用.all或.each,即使您将结果存储在控制器中的实例变量中。这可以使它看起来像实际上它是数据库中的某些东西时视图很慢。

尝试将一些调用放在视图中的不同位置进行基准测试,以查看时间的使用位置。

http://api.rubyonrails.org/classes/ActiveSupport/Benchmarkable.html#method-i-benchmark

为看你是什么查询正在进行和定位丢失索引等解释是得心应手。

http://guides.rubyonrails.org/active_record_querying.html#running-explain

+0

不知道第一部分。我会研究它。谢谢! – Sebastialonso