我有一个Movie
模型,包含大约15,000个项目和一个{3500}的Dvd
模型。
以下查询是使用在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
答案 0 :(得分:4)
您可以直接连接到数据库CLI,然后使用PostgresQL EXPLAIN
命令获取有关如何运行查询的信息。这可以显示您可以向表中添加索引以加快速度的位置。 Postgres docs解释(看我在那里做了什么?)EXPLAIN
更详细。
答案 1 :(得分:4)
您负责这些查询的代码是什么?你正在使用急切加载吗?您的查询应该是:
DVD.includes(:电影).where(无论如何)#assuming DVD有很多电影
这应该减少查询/请求的数量。到你的数据库。您的查询表明您可能遇到N + 1问题。
你也应该在电影桌上有dvd_id的数据库索引,因为它是一个外键。
答案 2 :(得分:0)
确保至少在dvd_id上有索引。 如果您可以在(dvd_id,scene)上创建复合索引,那么您的查询将是完全最优的,无法进一步优化。
换句话说,只需执行
即可CREATE INDEX movies_dvd_id_scene_idx ON movies (dvd_id, scene);
你应该全部设置
答案 3 :(得分: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应用和数据库都托管在相同区域(欧盟或美国)。