2

運行緩慢簡單的Postgres查詢我有一個Movie模型大約15,000項和一個Dvd模型3500在Heroku

下列查詢是使用起重機的Postgres數據庫在Heroku上運行簡單的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 
+1

請按照以下要求顯示'EXPLAIN(BUFFERS,ANALYZE)'和其他信息:http://stackoverflow.com/tags/postgresql-performance/info –

回答

4

您可以直接連接到數據庫CLI,然後使用PostgreSQL的EXPLAIN命令來獲取它如何運行你的查詢信息。這可以顯示可以在表格中添加索引的位置,以加快速度。 Postgres docs解釋(看看我在那裏做了什麼?)EXPLAIN更詳細。

4

你的代碼負責這些查詢?你正在使用急切的加載?您的查詢應該是這樣的:

DVD.includes(:電影)。哪裏(什麼)#assuming DVD有許多電影

這將減少查詢/請求數。到你的數據庫。您的查詢表明您可能有N + 1個問題。

您應該在dvd_id的電影表上擁有一個數據庫索引,因爲它是一個外鍵。

0

請確保您至少有dvd_id的索引。 如果您可以在(dvd_id,scene)上創建複合索引,那麼您的查詢將是完全最優化的,無法進一步優化。

換句話說,只需要執行

CREATE INDEX movies_dvd_id_scene_idx ON movies (dvd_id, scene); 

,你應該是所有設置

+1

你說「完全最優化」就好像這樣的事情可以確定一樣而不是通過嚴格的實際數據測試,生產查詢屍體以及系統運行的硬件限制。例如:向索引添加第二個字段會使密鑰大小變大,從而降低索引塊中的密鑰密度。這可能會導致難以完全緩存索引,或導致索引樹深度增加得更快,從而需要額外的查找來滿足查詢。如果場景/ dvd_id的平均基數接近1,那麼額外的場幾乎不會帶來好處。 – dbenhur

+0

我同意一般。但是,在這種情況下,考慮到數據量(只有15k行),使用這個配方不可能造成傷害,並且不需要任何修改,並且需要從OP重新索取更多信息。從這個意義上講,它是完全最佳的。 – mvp

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應用程序和數據庫託管在相同區域(歐盟或美國)。