2015-12-02 54 views
3

我有一個模型,我命名爲User Rails應用程序,它有一個屬性name(Rails)的時候使用ActiveRecord的。凡和。選擇

比方說,我想找到所有Usersname一個特定的字符串相匹配。

在Rails控制檯,我可以這樣做:

OPTION 1

User.where("name LIKE 'string'")

這是非常快的。

OPTION 2

User.select{|u| u.name == "string"}

這是極其緩慢。它適用於小型數據庫,但如果您有成千上萬的用戶,則似乎會嘗試先將所有Users加載到內存中,然後在塊中對其進行迭代。

這是否意味着選項2總是錯的? .select的正確用例是什麼,那麼什麼時候優於.where

我在我的應用程序中寫了一堆代碼,使用.select工作正常,但現在我嘗試在非常大的表上使用,我看到我可能做錯了什麼。

回答

11

選擇:http://apidock.com/rails/ActiveRecord/QueryMethods/select

「這將生成對象的數組從數據庫中的範圍內,把它們轉換成一個陣列,並使用陣列#選擇通過它們迭代」。

所以,它太慢了,因爲它從數據庫中提取所有東西,將它們逐個轉換成Ruby對象,然後運行你給它們的塊。如果你有一個包含100,000行的數據庫表,這意味着實例化100,000個紅寶石對象並在其上運行你的塊。 Ruby很慢,所以這很慢。

使用where基本上只是放在一起的SQL語句,並讓數據庫處理它。數據庫是快速的 - 如果速度是一個優先事項,那麼只要你可以推遲到數據庫,你應該這樣做。如果您有一個包含100,000行的數據庫表,但只有10個表匹配您的where查詢,那麼數據庫將處理過濾,而Ruby將只接收10行,因此只需要實例化10個Ruby對象,而不是100,000。

幾乎總是,你會想要使用where而不是select。那麼,你什麼時候可以使用select?那麼當你想根據一些比較難以轉換爲SQL的ruby條件過濾相對較少的記錄時,你會使用它(通常與where一起使用)。

例子:

User.where(account_cancelled: true).select do |u| 
    # perform complex ruby logic on user 
    # that would be hard to do with plain SQL 
    # (note, this will only act on the subset of 
    # users returned from the where clause) 
end 

所以,只要你合理的可使用where而非select,你應該這樣做。

(有也是在文檔中提到的第二個使用select:「修改用於查詢的SELECT語句,使只有某些字段檢索」 - 但是這不是你的問題,你要處理的使用)

+0

但是'.select'的正確用例是什麼,那麼什麼時候比'.where'更適合? (我知道它也可以用來限制列的數據庫查詢,但這不是我所問的用例) – sandre89

+2

增加了一個例子 –

+0

Rails 4添加了.find_by方法,它基本上與where相同 - 它是值得的閱讀Rails風格指南,該指南提供了有關它最常用的用法的更多詳細信息 - https://github.com/bbatsov/rails-style-guide#find_by –