所以我的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次。
问题是,我不知道如何识别生成此文件的文件和代码行。您对我该怎么做有任何想法吗?从这些日志中,找到我的代码在哪里。
答案 0 :(得分:3)
这看起来像一个N+1问题。您正在遍历每个用户,并显示其订阅顺序,但是每次都进行SQL查询。
这意味着很多SQL查询,这会导致较高的加载时间。通常,这意味着您将必须告诉Rails在单个SQL查询中加载联接的模型,而不是在首次调用它时加载它。 includes方法将使您做到这一点。
将bullet gem添加到您的应用中将帮助您发现并解决N + 1个问题。