Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 在Heroku上运行缓慢的简单Postgres查询_Ruby On Rails_Postgresql_Activerecord_Heroku_Postgresql Performance - Fatal编程技术网

Ruby on rails 在Heroku上运行缓慢的简单Postgres查询

Ruby on rails 在Heroku上运行缓慢的简单Postgres查询,ruby-on-rails,postgresql,activerecord,heroku,postgresql-performance,Ruby On Rails,Postgresql,Activerecord,Heroku,Postgresql Performance,我有一个电影型号,大约15000件,还有一个Dvd型号,3500件 以下查询是使用运行在Heroku上的Crane Postgres db的简单Rails关联。我想知道为什么下面的查询需要这么长时间,以及如何最终缩短查询时间 2012-10-24T05:42:19+00:00 app[postgres]: [30-1] [BLACK] LOG: duration: 57.914 ms statement: SELECT "movies".* FROM "movies" WHERE "mo

我有一个
电影
型号,大约15000件,还有一个
Dvd
型号,3500件

以下查询是使用运行在Heroku上的Crane Postgres db的简单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

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

您负责这些查询的代码是什么?您使用的是即时加载吗?您的查询应该类似于:

DVD.包括(:电影)。在哪里(无论什么)#假设DVD有很多电影

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


您还应该在movies表中为dvd\u id设置一个数据库索引,因为它是一个外键。

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

换句话说,就是执行

CREATE INDEX movies_dvd_id_scene_idx ON movies (dvd_id, scene);
你应该准备好了

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

平均而言(~80ms),这是在不同大陆上运行的查询通常需要的持续时间。确保你的Heroku应用程序和数据库都位于同一地区(欧盟或美国)。

你说“完全最优”,好像这样的事情可以在抽象中确定,而不是通过使用实际数据、生产查询尸体和系统运行的硬件约束进行严格测试。例如:向索引中添加第二个字段会使键的大小变大,从而降低索引块中的键密度。这会使完全缓存索引变得更加困难,或者导致索引树深度更快地增加,从而需要额外的搜索来满足查询。如果scenes/dvd_id的平均基数接近1,那么额外的字段几乎永远不会有好处。我大体上同意。但是,在这种情况下,考虑到数据量(仅15k行),使用此配方不可能造成伤害,并且不需要任何修改和重新要求OP提供更多信息。从这个意义上说,它是完全最优的。请在此处显示
解释(缓冲区,分析)
和其他要求的信息: