【问题标题】:Kaminari pagination slow with PostgreSQLPostgreSQL 的 Kaminari 分页速度很慢
【发布时间】:2016-01-10 11:05:59
【问题描述】:

我正在使用 Kaminari 在我的应用程序的一个页面上对两组数据进行分页。一组数据有大约 620 条记录,另一组大约有 150 条记录。与一些数据相比,数量并不多。

但是,分页部分的加载大约需要 900 毫秒。见:21:46:38 rails.1 | Rendered items/_paginator.erb (952.8ms)

显然这是由于 Kaminari 正在做的COUNT。更多细节在这里:https://github.com/amatsuda/kaminari/issues/545

我环顾四周,甚至在 SO 上也发现了类似的问题和大量关于如何加快 COUNT 的答案,但与 Kaminari 一起加快速度没有任何关系。

关于如何做到这一点的任何想法?

此请求的终端输出:

22:46:31 rails.1 |    (1.6ms)  SELECT COUNT(*) FROM "coasters" WHERE "coasters"."superseded_at" IS NULL AND (material = 'steel')
22:46:31 rails.1 |    (0.7ms)  SELECT COUNT(*) FROM "coasters" WHERE "coasters"."superseded_at" IS NULL AND (material = 'wood')
22:46:31 rails.1 |   Rendered shared/_breadcrumb_text.html.erb (9.6ms)
22:46:31 rails.1 |   Rendered shared/_fact_bar.html.erb (0.3ms)
22:46:32 rails.1 |   ParkChain Load (0.7ms)  SELECT "park_chains".* FROM "park_chains"
22:46:32 rails.1 |   Rendered theme_parks/parks/_filter_links.html.erb (11.5ms)
22:46:32 rails.1 |   Rendered theme_parks/coasters/_filter_links.html.erb (3.2ms)
22:46:33 rails.1 |    (0.4ms)  SELECT COUNT(*) FROM "parks"
22:46:33 rails.1 |   Rendered theme_parks/parks/_park_paginator.erb (1029.5ms)
22:46:33 rails.1 |   Park Load (1.2ms)  SELECT  "parks".* FROM "parks"  ORDER BY name ASC LIMIT 25 OFFSET 0
22:46:33 rails.1 |   Rendered theme_parks/parks/_park.html.erb (7.9ms)
22:46:33 rails.1 |   Rendered theme_parks/parks/_park_grid.html.erb (175.6ms)
22:46:34 rails.1 |   Rendered theme_parks/parks/_park_paginator.erb (961.1ms)
22:46:36 rails.1 |    (1.7ms)  SELECT COUNT(DISTINCT "coasters"."id") FROM "coasters" LEFT OUTER JOIN "parks" ON "parks"."id" = "coasters"."park_id" LEFT OUTER JOIN "cycles" ON "cycles"."coaster_id" = "coasters"."id" WHERE "coasters"."superseded_at" IS NULL
22:46:36 rails.1 |   Rendered theme_parks/coasters/_coaster_paginator.erb (1104.5ms)
22:46:36 rails.1 |   SQL (2.6ms)  SELECT  DISTINCT "coasters"."id", parks.name AS alias_0, coasters.name AS alias_1 FROM "coasters" LEFT OUTER JOIN "parks" ON "parks"."id" = "coasters"."park_id" LEFT OUTER JOIN "cycles" ON "cycles"."coaster_id" = "coasters"."id" WHERE "coasters"."superseded_at" IS NULL  ORDER BY parks.name ASC, coasters.name ASC LIMIT 25 OFFSET 0
22:46:36 rails.1 |   SQL (16.8ms)  SELECT "coasters"."id" AS t0_r0, "coasters"."name" AS t0_r1, "coasters"."inversions" AS t0_r2, "coasters"."material" AS t0_r3, "coasters"."notes" AS t0_r4, "coasters"."lat" AS t0_r5, "coasters"."lng" AS t0_r6, "coasters"."manufacturer_id" AS t0_r7, "coasters"."park_id" AS t0_r8, "coasters"."created_at" AS t0_r9, "coasters"."updated_at" AS t0_r10, "coasters"."slug" AS t0_r11, "coasters"."covering" AS t0_r12, "coasters"."style" AS t0_r13, "coasters"."model" AS t0_r14, "coasters"."layout" AS t0_r15, "coasters"."order_ridden" AS t0_r16, "coasters"."dates_ridden" AS t0_r17, "coasters"."on_ride_photo" AS t0_r18, "coasters"."powered" AS t0_r19, "coasters"."length" AS t0_r20, "coasters"."height" AS t0_r21, "coasters"."speed" AS t0_r22, "coasters"."coaster_sort" AS t0_r23, "coasters"."is_milestone" AS t0_r24, "coasters"."version_number" AS t0_r25, "coasters"."version_reason" AS t0_r26, "coasters"."version_ridden_after" AS t0_r27, "coasters"."position" AS t0_r28, "coasters"."relocated" AS t0_r29, "coasters"."renamed" AS t0_r30, "coasters"."rethemed" AS t0_r31, "coasters"."steel_10" AS t0_r32, "coasters"."wood_10" AS t0_r33, "coasters"."original_version_id" AS t0_r34, "coasters"."superseded_at" AS t0_r35, "parks"."id" AS t1_r0, "parks"."name" AS t1_r1, "parks"."location_1" AS t1_r2, "parks"."location_2" AS t1_r3, "parks"."location_3" AS t1_r4, "parks"."lat" AS t1_r5, "parks"."lng" AS t1_r6, "parks"."created_at" AS t1_r7, "parks"."updated_at" AS t1_r8, "parks"."location_4" AS t1_r9, "parks"."country" AS t1_r10, "parks"."park_chain_id" AS t1_r11, "parks"."notes" AS t1_r12, "parks"."visit_count" AS t1_r13, "parks"."dates_visited" AS t1_r14, "parks"."slug" AS t1_r15, "parks"."order_visited" AS t1_r16, "parks"."logo" AS t1_r17, "cycles"."id" AS t2_r0, "cycles"."coaster_id" AS t2_r1, "cycles"."notes" AS t2_r2, "cycles"."date" AS t2_r3, "cycles"."created_at" AS t2_r4, "cycles"."updated_at" AS t2_r5 FROM "coasters" LEFT OUTER JOIN "parks" ON "parks"."id" = "coasters"."park_id" LEFT OUTER JOIN "cycles" ON "cycles"."coaster_id" = "coasters"."id" WHERE "coasters"."superseded_at" IS NULL AND "coasters"."id" IN (21926, 22414, 21927, 21939, 21963, 21964, 21962, 21965, 21800, 21790, 21791, 21793, 21794, 21795, 22378, 21845, 21792, 21842, 21941, 22179, 22144, 22145, 22065, 22196, 22188)  ORDER BY parks.name ASC, coasters.name ASC
22:46:36 rails.1 |   Rendered theme_parks/coasters/_coaster.html.erb (273.5ms)
22:46:36 rails.1 |   Rendered theme_parks/coasters/_coaster_grid.html.erb (576.9ms)
22:46:37 rails.1 |   Rendered theme_parks/coasters/_coaster_paginator.erb (968.7ms)
22:46:37 rails.1 |   Rendered theme_parks/index.html.erb within layouts/application (6285.8ms)
22:46:38 rails.1 |   Rendered shared/_banner_slideshow.html.erb (0.1ms)
22:46:38 rails.1 |   Rendered shared/_flash_messages.html.erb (0.2ms)
22:46:38 rails.1 | Completed 200 OK in 7547ms (Views: 7216.3ms | ActiveRecord: 33.3ms)

更新:

【问题讨论】:

  • 如果单个 SQL 调用需要将近 1 秒的时间来运行,则说明您的数据库配置有误。我有一个有 570K 行的表,它需要 333 毫秒。
  • @PhilipHallstrom 好的。当我意识到我的记录数量远不及像你这样的其他人拥有的数量时,我将如何找到导致数据库端减速的原因并重新配置它以更快。
  • @PhilipHallstrom 如果我只运行一个标准的 COUNT 查询,它真的很快,但是当它是 Kaminari 的一部分时,它就很慢,并且分页渲染需要 900 - 1000 毫秒。所以它是 Kaminari,但我找不到修复它的解决方案。
  • 所以看起来coaster_paginator.erb有问题,但是_coaster.html.erb和_coaster_grid.html.erb也比较慢。
  • Views: 7216.3ms | ActiveRecord: 33.3ms: 你的数据库好像和它无关,实际与数据库的交互不到总渲染时间的0.5%。还有其他一些事情会减慢这个过程。您可能需要探查器才能找到它。

标签: ruby-on-rails database pagination kaminari


【解决方案1】:

我做了一些分析。我测试过 PostgreSQL 和 MySQL 上的渲染速度是一样的。在我将查询优化到 300 毫秒后,渲染为 2500-3500 毫秒。有两件事让我的渲染速度更快。

  1. 我注释掉了gem 'bootstrap-kaminari-views',渲染减少到1000ms,但它很难看。如果我将 erb 文件从该 gem 复制到我的 app/views/kaminari 文件夹,我也会得到 1000 毫秒,它看起来不错。这是一个惊喜。
  2. 我尝试了.page(params[:page]).without_count,渲染时间减少到了 150 毫秒。它是不同类型的分页,所以我必须考虑它是否适合我的应用程序。

顺便说一句,它在 Rails 4.2 上更快,现在我升级到 5.2 并遇到了这个问题。

【讨论】:

    猜你喜欢
    • 2013-11-10
    • 1970-01-01
    • 2012-06-25
    • 2016-05-19
    • 2016-12-18
    • 2016-08-11
    • 2018-07-19
    • 2013-04-20
    • 2015-05-15
    相关资源
    最近更新 更多