मैं रेल 4.0.0 और रूबी 2.0.0 का उपयोग कर रहा हूं। मेरा Post
(जैसा कि ब्लॉग पोस्ट में है) मॉडल उपयोगकर्ता के उपयोगकर्ता_नाम, first_name, last_name के संयोजन के साथ उपयोगकर्ता से जुड़ा हुआ है। मैं डेटा माइग्रेट करना चाहता हूं ताकि पोस्ट विदेशी उपयोगकर्ताओं द्वारा उपयोगकर्ताओं से जुड़ी हो, जो उपयोगकर्ता की आईडी है।मैं ActiveRecord find_in_batches क्वेरी को कैसे अनुकूलित करूं?
मेरे पास posts
तालिका में लगभग 11 मिलियन रिकॉर्ड हैं।
मैं लिनक्स सर्वर पर एक रेक कार्य का उपयोग कर डेटा माइग्रेट करने के लिए नीचे कोड चला रहा हूं। हालांकि, मेरा काम अलग-अलग मेमोरी का उपभोग करने के कारण, विशेष रूप से नीचे दिए गए कोड के कारण, सेवर द्वारा "मार डाला" रहता है।
मैंने पाया है कि 20 के लिए batch_size
कम करने और sleep(60)
को sleep(10)
बढ़ती कार्य मार डाला जा रहा है बिना कुल में अधिक रिकॉर्ड को अपडेट करते, अब चलाने के लिए अनुमति देता है, लेकिन काफी अधिक समय लगता है।
मैं इस कोड को गति और स्मृति उपयोग के लिए कैसे अनुकूलित कर सकता हूं?
Post.where(user_id: nil).find_in_batches(batch_size: 1000) do |posts|
puts "*** Updating batch beginning with post #{posts.first.id}..."
sleep(10) # Hopefully, saving some memory usage.
posts.each do |post|
begin
user = User.find_by(user_name: post.user_name, first_name: post.first_name, last_name: post.last_name)
post.update(user_id: user.id)
rescue NoMethodError => error # user could be nil, so user.id will raise a NoMethodError
puts "No user found."
end
end
puts "*** Finished batch."
end
वहाँ 'find_in_batches' तुलना में एक बेहतर तरीका है एआर Iff अद्यतन, कि एक स्वागत योग्य जवाब होगा! – sealocal
आप मॉडल परत के माध्यम से जाने के बजाय इसे एक 'अद्यतन' कथन के साथ कर सकते हैं। इसके अलावा 'नींद' का उपयोग स्मृति उपयोग पर शून्य प्रभाव पड़ता है, यह बस इसे धीमा कर देता है। यदि आप स्मृति उपयोग पर दीवार के खिलाफ वास्तव में हैं, तो प्रत्येक पुनरावृत्ति के बाद 'जीसी.स्टार्ट' पर कॉल करें। बहुत यकीन है कि आप यह सब एक साधारण प्रवासन में कर सकते हैं। – tadman