仅在生产中发生错误时如何调试Rails应用程序?

时间:2018-09-17 08:17:21

标签: ruby-on-rails postgresql heroku

所以我的rails Web应用程序托管在Heroku上,并且我从Heroku中收到H12错误,这意味着该请求需要30多秒才能被执行。在开发过程中,完全运行但最终工作所需的时间也很长。所以我在开发模式下没有任何错误。

当我查看日志时,我得到的提示是什么问题:

SubscriptionOrder Load (19.4ms)  SELECT  "subscription_orders".* FROM "subscription_orders" WHERE "subscription_orders"."user_id" = $1 AND "subscription_orders"."state" = $2 ORDER BY "subscription_orders"."id" DESC LIMIT $3  [["user_id", 107], ["state", "paid"], ["LIMIT", 1]]
  CACHE SubscriptionOrder Load (0.0ms)  SELECT  "subscription_orders".* FROM "subscription_orders" WHERE "subscription_orders"."user_id" = $1 AND "subscription_orders"."state" = $2 ORDER BY "subscription_orders"."id" DESC LIMIT $3  [["user_id", 107], ["state", "paid"], ["LIMIT", 1]]
  SubscriptionOrder Load (0.7ms)  SELECT  "subscription_orders".* FROM "subscription_orders" WHERE "subscription_orders"."user_id" = $1 AND "subscription_orders"."state" = $2 AND "subscription_orders"."running" = $3 ORDER BY "subscription_orders"."id" DESC LIMIT $4  [["user_id", 107], ["state", "paid"], ["running", "t"], ["LIMIT", 1]]
  CACHE SubscriptionOrder Load (0.0ms)  SELECT  "subscription_orders".* FROM "subscription_orders" WHERE "subscription_orders"."user_id" = $1 AND "subscription_orders"."state" = $2 ORDER BY "subscription_orders"."id" DESC LIMIT $3  [["user_id", 107], ["state", "paid"], ["LIMIT", 1]]
   (4.4ms)  SELECT COUNT(*) FROM "orders" WHERE (user_id = 107 AND (status = '') IS NOT FALSE AND created_at >= '2018-09-17 10:00:38.559259')
  CACHE SubscriptionOrder Load (0.0ms)  SELECT  "subscription_orders".* FROM "subscription_orders" WHERE "subscription_orders"."user_id" = $1 AND "subscription_orders"."state" = $2 AND "subscription_orders"."running" = $3 ORDER BY "subscription_orders"."id" DESC LIMIT $4  [["user_id", 107], ["state", "paid"], ["running", "t"], ["LIMIT", 1]]
  CACHE SubscriptionOrder Load (0.0ms)  SELECT  "subscription_orders".* FROM "subscription_orders" WHERE "subscription_orders"."user_id" = $1 AND "subscription_orders"."state" = $2 ORDER BY "subscription_orders"."id" DESC LIMIT $3  [["user_id", 107], ["state", "paid"], ["LIMIT", 1]]
   (0.6ms)  SELECT COUNT(*) FROM "orders" WHERE (user_id = 107 AND (status = '') IS NOT FALSE AND created_at >= '2018-09-17 10:00:38')
   (1.4ms)  SELECT COUNT(*) FROM "free_meals" WHERE (used = 'f' AND user_id = 107)
  CACHE SubscriptionOrder Load (0.0ms)  SELECT  "subscription_orders".* FROM "subscription_orders" WHERE "subscription_orders"."user_id" = $1 AND "subscription_orders"."state" = $2 ORDER BY "subscription_orders"."id" DESC LIMIT $3  [["user_id", 107], ["state", "paid"], ["LIMIT", 1]]
  CACHE SubscriptionOrder Load (0.0ms)  SELECT  "subscription_orders".* FROM "subscription_orders" WHERE "subscription_orders"."user_id" = $1 AND "subscription_orders"."state" = $2 ORDER BY "subscription_orders"."id" DESC LIMIT $3  [["user_id", 107], ["state", "paid"], ["LIMIT", 1]]
  Subscription Load (0.4ms)  SELECT  "subscriptions".* FROM "subscriptions" WHERE "subscriptions"."id" = $1 LIMIT $2  [["id", 6], ["LIMIT", 1]]
  CACHE SubscriptionOrder Load (0.0ms)  SELECT  "subscription_orders".* FROM "subscription_orders" WHERE "subscription_orders"."user_id" = $1 AND "subscription_orders"."state" = $2 ORDER BY "subscription_orders"."id" DESC LIMIT $3  [["user_id", 107], ["state", "paid"], ["LIMIT", 1]]
  CACHE SubscriptionOrder Load (0.0ms)  SELECT  "subscription_orders".* FROM "subscription_orders" WHERE "subscription_orders"."user_id" = $1 AND "subscription_orders"."state" = $2 ORDER BY "subscription_orders"."id" DESC LIMIT $3  [["user_id", 107], ["state", "paid"], ["LIMIT", 1]]
  CACHE SubscriptionOrder Load (0.0ms)  SELECT  "subscription_orders".* FROM "subscription_orders" WHERE "subscription_orders"."user_id" = $1 AND "subscription_orders"."state" = $2 AND "subscription_orders"."running" = $3 ORDER BY "subscription_orders"."id" DESC LIMIT $4  [["user_id", 107], ["state", "paid"], ["running", "t"], ["LIMIT", 1]]
  CACHE SubscriptionOrder Load (0.0ms)  SELECT  "subscription_orders".* FROM "subscription_orders" WHERE "subscription_orders"."user_id" = $1 AND "subscription_orders"."state" = $2 ORDER BY "subscription_orders"."id" DESC LIMIT $3  [["user_id", 107], ["state", "paid"], ["LIMIT", 1]]
  CACHE  (0.0ms)  SELECT COUNT(*) FROM "orders" WHERE (user_id = 107 AND (status = '') IS NOT FALSE AND created_at >= '2018-09-17 10:00:38.559259')
  CACHE SubscriptionOrder Load (0.0ms)  SELECT  "subscription_orders".* FROM "subscription_orders" WHERE "subscription_orders"."user_id" = $1 AND "subscription_orders"."state" = $2 AND "subscription_orders"."running" = $3 ORDER BY "subscription_orders"."id" DESC LIMIT $4  [["user_id", 107], ["state", "paid"], ["running", "t"], ["LIMIT", 1]]
  CACHE SubscriptionOrder Load (0.0ms)  SELECT  "subscription_orders".* FROM "subscription_orders" WHERE "subscription_orders"."user_id" = $1 AND "subscription_orders"."state" = $2 ORDER BY "subscription_orders"."id" DESC LIMIT $3  [["user_id", 107], ["state", "paid"], ["LIMIT", 1]]
  CACHE  (0.0ms)  SELECT COUNT(*) FROM "orders" WHERE (user_id = 107 AND (status = '') IS NOT FALSE AND created_at >= '2018-09-17 10:00:38')
  CACHE  (0.0ms)  SELECT COUNT(*) FROM "free_meals" WHERE (used = 'f' AND user_id = 107)
  CACHE SubscriptionOrder Load (0.0ms)  SELECT  "subscription_orders".* FROM "subscription_orders" WHERE "subscription_orders"."user_id" = $1 AND "subscription_orders"."state" = $2 ORDER BY "subscription_orders"."id" DESC LIMIT $3  [["user_id", 107], ["state", "paid"], ["LIMIT", 1]]
  CACHE SubscriptionOrder Load (0.0ms)  SELECT  "subscription_orders".* FROM "subscription_orders" WHERE "subscription_orders"."user_id" = $1 AND "subscription_orders"."state" = $2 ORDER BY "subscription_orders"."id" DESC LIMIT $3  [["user_id", 107], ["state", "paid"], ["LIMIT", 1]]
  CACHE Subscription Load (0.0ms)  SELECT  "subscriptions".* FROM "subscriptions" WHERE "subscriptions"."id" = $1 LIMIT $2  [["id", 6], ["LIMIT", 1]]
  CACHE SubscriptionOrder Load (0.0ms)  SELECT  "subscription_orders".* FROM "subscription_orders" WHERE "subscription_orders"."user_id" = $1 AND "subscription_orders"."state" = $2 ORDER BY "subscription_orders"."id" DESC LIMIT $3  [["user_id", 107], ["state", "paid"], ["LIMIT", 1]]
  CACHE SubscriptionOrder Load (0.0ms)  SELECT  "subscription_orders".* FROM "subscription_orders" WHERE "subscription_orders"."user_id" = $1 AND "subscription_orders"."state" = $2 ORDER BY "subscription_orders"."id" DESC LIMIT $3  [["user_id", 107], ["state", "paid"], ["LIMIT", 1]]
  CACHE SubscriptionOrder Load (0.0ms)  SELECT  "subscription_orders".* FROM "subscription_orders" WHERE "subscription_orders"."user_id" = $1 AND "subscription_orders"."state" = $2 AND "subscription_orders"."running" = $3 ORDER BY "subscription_orders"."id" DESC LIMIT $4  [["user_id", 107], ["state", "paid"], ["running", "t"], ["LIMIT", 1]]
  CACHE SubscriptionOrder Load (0.0ms)  SELECT  "subscription_orders".* FROM "subscription_orders" WHERE "subscription_orders"."user_id" = $1 AND "subscription_orders"."state" = $2 ORDER BY "subscription_orders"."id" DESC LIMIT $3  [["user_id", 107], ["state", "paid"], ["LIMIT", 1]]
  CACHE  (0.0ms)  SELECT COUNT(*) FROM "orders" WHERE (user_id = 107 AND (status = '') IS NOT FALSE AND created_at >= '2018-09-17 10:00:38.559259')

...等等,依此类推。 SubscriptionOrder DB请求运行大约100次。

问题是,我不知道如何识别生成此文件的文件和代码行。您对我该怎么做有任何想法吗?从这些日志中,找到我的代码在哪里。

1 个答案:

答案 0 :(得分:3)

这看起来像一个N+1问题。您正在遍历每个用户,并显示其订阅顺序,但是每次都进行SQL查询。

这意味着很多SQL查询,这会导致较高的加载时间。通常,这意味着您将必须告诉Rails在单个SQL查询中加载联接的模型,而不是在首次调用它时加载它。 includes方法将使您做到这一点。

bullet gem添加到您的应用中将帮助您发现并解决N + 1个问题。