2011-10-24 56 views
0

因此,我想知道以下哪項更有效。最好的答案實際上是,我怎麼能在將來爲自己弄清楚這一點。Rails 3中訂單查詢的效率3

的兩個查詢是:

# id integer 
# created_at datetime 
# collection_id integer 
# updated_at datetime 
class Post < ActiveRecord::Base 
    belongs_to :collection 
end 

Post.where(:collection_id => collection_id).order(:updated_at).last 

VS

Post.where(:collection_id => collection_id).order("updated_at DESC").first 

所以,第2部分的問題:

1)那些語句的是更有效? (除非我有一個錯字,他們應該是等價的)

2)怎麼會我已經回答了我這個問題?

我假設沒有索引。我也很想知道答案是否會根據查詢的collect_id部分的結果集的預期大小而變化。

回答

2

至少在Rails 3.1中,您的兩個查詢實際上都會在數據庫上運行相同的查詢。 Rails很聰明,知道在查詢上調用.last應該顛倒順序並將其限制爲單個請求。因此,下面的行實際上只是將ORDER BY updated_at DESC LIMIT 1添加到您的查詢結尾。換句話說,這條線不返回所有記錄從數據庫,創建ActiveRecord對象爲他們每個人,並然後返回最後一個,這將是效率要低得多。

Post.where(:collection_id => collection_id).order(:updated_at).last 
1

如果你看控制檯,你會看到(1)什麼樣的查詢(或查詢)實際上正在執行;(2)它花時間來執行。這將是追蹤效率的基本方式。

在生產中也有類似NewRelic RPM工具會給你警告/速度/時間來執行查詢分析。我想認爲免費版本會做效率分析,但只保留前30分鐘的應用程序運行時記錄。

一般(但不是嚴格意義上),您發送的查詢的數量越少,越好,部分原因是因爲它涉及到Rails和數據庫之間少往返。

如果你想要的東西也是免費的,也許更加可重複,那麼你可以添加一些性能測試,反覆運行查詢,每次運行查詢時間,並確保查詢/控制器的行爲不如您選擇的某個基準,或者多次執行的平均時間低於某個閾值。

這種方法,如果他們需要更長的時間比預期的還可以用作是撞到最常在您的應用程序操作的守望者,失敗。測試只會涵蓋模擬環境,當然,可以用來作爲關鍵行爲是否與預期性能完全脫節的一般指示。