2

我有一个Movie包含大约 15,000 个项目的Dvd模型和一个包含 3500 个项目的模型。

以下查询是使用在 Heroku 上运行的 Crane Postgres 数据库的简单 Rails 关联。我想知道为什么以下查询需要这么长时间,以及我最终如何才能减少它的时间。

2012-10-24T05:42:19+00:00 app[postgres]: [30-1] [BLACK] LOG:  duration: 57.914 ms  statement: SELECT  "movies".* FROM "movies"  WHERE "movies"."dvd_id" = 37 ORDER BY scene LIMIT 1
2012-10-24T05:42:20+00:00 app[postgres]: [31-1] [BLACK] LOG:  duration: 77.086 ms  statement: SELECT  "movies".* FROM "movies"  WHERE "movies"."dvd_id" = 915 ORDER BY scene LIMIT 1
2012-10-24T05:42:20+00:00 app[postgres]: [32-1] [BLACK] LOG:  duration: 85.602 ms  statement: SELECT  "movies".* FROM "movies"  WHERE "movies"."dvd_id" = 108 ORDER BY scene LIMIT 1
2012-10-24T05:42:21+00:00 app[postgres]: [33-1] [BLACK] LOG:  duration: 70.147 ms  statement: SELECT  "movies".* FROM "movies"  WHERE "movies"."dvd_id" = 11 ORDER BY scene LIMIT 1
2012-10-24T05:42:21+00:00 app[postgres]: [34-1] [BLACK] LOG:  duration: 144.204 ms  statement: SELECT  "movies".* FROM "movies"  WHERE "movies"."dvd_id" = 6 ORDER BY scene LIMIT 1
2012-10-24T05:42:22+00:00 app[postgres]: [35-1] [BLACK] LOG:  duration: 56.623 ms  statement: SELECT  "movies".* FROM "movies"  WHERE "movies"."dvd_id" = 1956 ORDER BY scene LIMIT 1
2012-10-24T05:42:23+00:00 app[postgres]: [36-1] [BLACK] LOG:  duration: 64.860 ms  statement: SELECT  "movies".* FROM "movies"  WHERE "movies"."dvd_id" = 747 ORDER BY scene LIMIT 1
4

4 回答 4

4

您可以直接连接到数据库 CLI,然后使用 PostgresQLEXPLAIN命令获取有关它如何运行查询的信息。这可以显示您可以向表中添加索引以加快速度的地方。Postgres文档更详细地解释(看看我在那里做了什么?)EXPLAIN

于 2012-10-24T05:58:05.760 回答
4

负责这些查询的代码是什么?你在使用急切加载吗?您的查询应该是这样的:

DVD.includes(:movies).where(whatever) #假设 DVD 有很多电影

这应该会减少查询/请求的数量。到您的数据库。您的查询表明您可能有 N+1 个问题。

您还应该在电影表上为 dvd_id 建立一个数据库索引,因为它是一个外键。

于 2012-10-24T06:24:36.477 回答
0

确保您至少在 dvd_id 上有索引。如果您可以在 (dvd_id, scene) 上创建复合索引,您的查询将是完全优化的,无法进一步优化。

换句话说,只需执行

CREATE INDEX movies_dvd_id_scene_idx ON movies (dvd_id, scene);

你应该准备好了

于 2012-10-24T06:30:54.807 回答
0
duration: 57.914 ms
duration: 77.086 ms
duration: 85.602 ms
duration: 70.147 ms
duration: 144.204 ms
duration: 56.623 ms
duration: 64.860 ms

平均(约 80 毫秒),这是在不同大陆运行的查询所需的通常持续时间。确保您的 Heroku 应用程序和数据库都托管在同一地区(欧盟或美国)。

于 2017-12-05T20:26:26.683 回答