2009-09-29 35 views
1

好日子所有,驗證遺留表的ActiveRecord

我們正在從一個系統做數據遷移到Rails應用程序。我們正在使用的一些表格非常大,並且使用ActiveRecord一次將它們移動超過1條記錄需要很長時間。因此,我們採取了在SQL中複製表並在事後進行驗證。

的一個接一個的驗證檢查仍然很慢,但是從SQL的速度增加複製多彌補了它。但是,這並沒有解決我們是否能夠更快地進行驗證檢查的渴望。我們試圖將表拆分成塊,並將每個塊傳遞給一個線程,但實際上執行速度較慢。

的問題是,大桌子,當前迭代一行一行地做驗證,像這樣

Model.find_each do |m| 
    logger.info "M #{m.id} is not valid" unless m.valid? 
end 

人對如何加快這什麼建議?

感謝

同行

編輯我應該說,沒有具體的代碼。我們每個進程尋找對我們如何才能同時運行這個建議,給每個進程的數據塊,而不需要一臺機器

回答

0

我喜歡爲起點zgchurch的響應。

我想補充的是,線程是絕對不會幫助這裏,特別是因爲紅寶石使用綠色線程(至少在1.8.x的),所以沒有機會利用多個處理器反正。即使不是這種情況,這種操作很可能是IO操作量足夠大,以至於IO爭用會侵入任何多核優勢。

現在,如果你真的想加快這你應該看看實際的驗證,並找出更有效的方式來實現這些目標。只需加載所有行並實例化一個ActiveRecord對象就會趨向於在大多數驗證情況下支配性能。您可能會花費90-99.99%的時間來加載和卸載內存中的數據。

在這些類型的情況下,我傾向於去實現原始的SQL。您可以執行諸如驗證外鍵完整性比原始ActiveRecord驗證回調快幾萬倍的操作。當然,這種方法的可行性取決於您驗證的實際情況。即使你需要的東西比SQL更豐富一點,以確定有效性,你仍然可以或許獲得10-100倍的速度增加只是用更薄的SQL接口加載最小的數據,並直接檢查數據。如果是這樣的話,Perl或Python可能是原始性能的更好選擇。

+0

好點,我一直不願意嘗試和SQL複製驗證,但你可能是正確的,因爲它會提供最佳性能 – 2009-10-01 13:11:43

2

find_each使用find_in_batches,它在默認情況下,一次獲取1000行。您可以嘗試使用batch_size選項進行播放。你有以上的方式似乎非常優化;它是從批處理數據庫中獲取數據並迭代每個數據庫的,這些都是你需要做的。我會監視你的RAM,看看批量大小是否是最優的,如果你目前使用1.8。*,你也可以嘗試使用Ruby 1.9.1來加快速度。

http://api.rubyonrails.org/classes/ActiveRecord/Batches/ClassMethods.html#M001846