2011-11-16 18 views
6

मेरे पास बेसबॉल टूल है जो उपयोगकर्ताओं को प्लेयर के ऐतिहासिक बल्लेबाजी आंकड़ों का विश्लेषण करने की अनुमति देता है। उदाहरण के लिए, रात-समय की स्थितियों के दौरान पिछले 7 दिनों में ए-रॉड कितनी हिट करता है? मैं समय सीमा का विस्तार करना चाहता हूं ताकि उपयोगकर्ता 365 दिनों तक किसी खिलाड़ी के बल्लेबाजी आंकड़ों का विश्लेषण कर सके। हालांकि, ऐसा करने के लिए कुछ गंभीर प्रदर्शन अनुकूलन की आवश्यकता है। यहाँ मेरी मॉडल के वर्तमान सेट कर रहे हैं:बड़ी संख्या में रिकॉर्ड्स अपडेट करना - प्रदर्शन अनुकूलन

class AtBat < ActiveRecord::Base 
    belongs_to :batter 
    belongs_to :pitcher 
    belongs_to :weather_condition 

    ### DATA MODEL ### 
    # id 
    # batter_id 
    # pitcher_id 
    # weather_condition_id 
    # hit (boolean) 
    ################## 
end 

class BattingStat < ActiveRecord::Base 
    belongs_to :batter 
    belongs_to :recordable, :polymorphic => true # e.g., Batter, Pitcher, WeatherCondition 

    ### DATA MODEL ### 
    # id 
    # batter_id 
    # recordable_id 
    # recordable_type 
    # hits7 
    # outs7 
    # at_bats7 
    # batting_avg7 
    # ... 
    # hits365 
    # outs365 
    # at_bats365 
    # batting_avg365 
    ################## 
end 

class Batter < ActiveRecord::Base 
    has_many :batting_stats, :as => :recordable, :dependent => :destroy 
    has_many :at_bats, :dependent => :destroy 
end 

class Pitcher < ActiveRecord::Base 
    has_many :batting_stats, :as => :recordable, :dependent => :destroy 
    has_many :at_bats, :dependent => :destroy 
end 

class WeatherCondition < ActiveRecord::Base 
    has_many :batting_stats, :as => :recordable, :dependent => :destroy 
    has_many :at_bats, :dependent => :destroy 
end 

एक उचित लंबाई में मेरे सवाल रखने के लिए, मेरे बयान मैं batting_stats तालिका अद्यतन करने के लिए क्या कर रहा हूँ के बजाय कोड का एक समूह को कॉपी करते हैं। चलो 7 दिनों के साथ शुरू करते हैं।

  1. पिछले 7 दिनों में सभी at_bat रिकॉर्ड्स पुनर्प्राप्त करें। रिकॉर्ड at_bat प्रत्येक पर
  2. दोहराएं ...
  3. एक at_bat रिकॉर्ड को देखते हुए,, जुड़े बल्लेबाज और संबद्ध WEATHER_CONDITION हड़पने सही batting_stat रिकॉर्ड (BattingStat.find_or_create_by_batter_and_recordable (बल्लेबाज, WEATHER_CONDITION) मिल जाए, तो batting_stat रिकॉर्ड को अपडेट करें।
  4. दोहराएँ । बल्लेबाज और घड़े के लिए चरण 3 (recordables)

कदम 1-4 के साथ-साथ अन्य समय अवधि के लिए दोहराया जाता है - 15 दिन, 30 दिन, आदि

अब मुझे लगता है कि यह कैसे श्रमसाध्य होगा सेवा मेरे इन अद्यतनों को बनाने के लिए हर दिन एक स्क्रिप्ट चलाएं यदि मैं समय सारिणी को 7/15/30 से 7/15/30/45/60/90/180/365 तक विस्तारित करना था।

तो मेरा सवाल यह है कि आप इसे प्रदर्शन के उच्चतम स्तर पर चलाने के लिए कैसे पहुंचेंगे?

+0

मैं एक गोल्फ अनुप्रयोग के लिए इसी तरह की प्रणाली का निर्माण किया है। मैं साझा करने के लिए तैयार हूं लेकिन इसके लिए एक बहुत व्यापक व्याख्या की आवश्यकता है। क्या आप अपने आर्किटेक्चर को बदलने के इच्छुक हैं या आप वर्तमान में आपके पास मौजूद आर्किटेक्चर को अनुकूलित करने के लिए एक तरीका ढूंढ रहे हैं? – mnelson

+0

मुझे यह सुनने की बहुत सराहना की जाएगी कि आपने यह कैसे किया। आर्क को अपडेट करने के लिए तैयार, लेकिन सड़क की जांच। – keruilin

+0

आप कितने रिकॉर्ड से निपट रहे हैं? बेसबॉल के लिए कई डेटा अंक नहीं हो सकते हैं, निश्चित रूप से (सैकड़ों हजारों?)। तुम सिर्फ एक नक्शे में स्मृति में बहुत कुछ है, संभवतः खिलाड़ी के आधार पर विभाजित कर सकते हैं नहीं यदि आवश्यकता हुई, और मक्खी पर यह सब की गणना? –

उत्तर

3

एआर वास्तव में इस तरह की थोक प्रसंस्करण करने के लिए नहीं है। आप एसक्यूएल में उचित रूप से ड्रॉप करके और INSERT FROM SELECT (या शायद आपके लिए यह एक मणि का उपयोग करके) को अपने बैच अपडेट करने से बेहतर कर सकते हैं।

1

आपको अनिवार्य रूप से डेटा को इस तरह से स्टोर करने की आवश्यकता है कि आप अंतिम दिन को बंद कर सकें और इसे इस तरह से पहले नए दिन के साथ प्रतिस्थापित कर सकें कि आपको कुल को दोबारा नहीं बदला जाना है।

ऐसा करने का एक तरीका अतिरिक्त के मूल्य को संग्रहित करना होगा और उसके द्वारा अंतिम दिन मूल्य घटाएं और फिर नया दिन मान जोड़ें और फिर 15/30/90/365 तक विभाजित करें।

कि 3. में 366 आपरेशन बदल जाता है अब डेटाबेस 363 आपरेशन की तुलना में धीमी से पढ़ रही है?

यह भी, पुनरावृत्तियों पर बचाता है तो तुम सब करने की जरूरत है जो प्रत्येक दिन मौसम की शर्तों अद्यतन करने की आवश्यकता की जांच है।

0

हमें यूएस किराये के 600,000 रिकॉर्ड की बैच लोडिंग के साथ एक ही समस्या है प्रत्येक सप्ताह डेटा। प्रत्येक रिकॉर्ड को संसाधित करने के लिए क्रमशः 24 घंटे लगेंगे। लेकिन यह आवश्यक रूप से डेटाबेस नहीं था जो बाधा थी - हालांकि प्रत्येक सम्मिलन में निश्चित समय लगता था, डेटाबेस को गतिविधि द्वारा अधिकतम/pegged/flatlined नहीं किया गया था।

मुझे पता था कि व्यक्तिगत स्ट्रिंग रिकॉर्ड में फ़ाइल को विभाजित करना आसान और तेज़ था। हमारे मामले में, इनपुट फ़ाइल एक्सएमएल के रूप में थी, और मैंने ... टैग पर फ़ाइल को विभाजित करने के लिए एक सरल जावा स्ट्रिंगटोकनाइज़र का उपयोग किया।

कि जल्दी से मुझे एक्सएमएल किराए पर लेने की संपत्ति के बारे में जानकारी है कि मैं पार्स और आयात करने की जरूरत युक्त के टुकड़े का एक बड़ा सरणी दे दी है।

मैंने फिर 20 थ्रेड के पूल बनाने के लिए जावा थ्रेडपूल एक्स्सेलर/फ्यूचरटास्क/कॉल करने योग्य सम्मेलन का उपयोग किया जो इनपुट के रूप में प्रत्येक एक्सएमएल स्निपेट ले लेगा, प्रासंगिक डेटा निकाल देगा और डेटाबेस आवेषण करेगा। मुझे नहीं पता कि आपके आर्किटेक्चर के बराबर क्या होगा, लेकिन मुझे लगता है कि कुछ ऐसा ही है।

अंत में, मैं विभिन्न परीक्षण परिस्थितियों में डेटाबेस सर्वर लोड की निगरानी के द्वारा रिकॉर्ड प्रवाह क्षमता को अधिकतम करने के ThreadPool के आकार को समायोजित करने में सक्षम था। हम 25

0

की एक ThreadPool आकार जब मैं पहले इस तरह का काम करना पड़ा है पर बसे, मैं अपने एसक्यूएल संदर्भ बाहर खराब है और कैसे जटिल अपडेट करने के लिए साथ मेरे मन को ताज़ा करें। आमतौर पर आप एक अच्छी क्वेरी के साथ लघु फैशन में बहुत सारे अद्यतन कर सकते हैं। साथ ही, आपको क्वेरी के साथ सीधा सहायता मिलनी चाहिए (अपनी स्कीमा पोस्ट करें और यदि वे वास्तव में विशाल हैं तो एक गिस्ट में प्रश्न पूछना)

मुझे हाल ही में एक counter_cache मान बीज करना था, और इसे एक समूह के रूप में करने से पहले गहरे लाल रंग का कोड माता-पिता लोड हो रहा है और अपने बच्चों को गिनती, मैं इस प्रश्न के एक शॉट दिया:

UPDATE rates r SET children_count = child_counts.my_count from (SELECT parent_id, count(*) as my_count FROM rates GROUP BY parent_id having parent_id is not null) as child_counts where child_counts.parent_id = r.id; 

जो बस कुछ ही सेकेंड

में 200k पंक्तियों अद्यतन आप एक क्वेरी, और अगर में ऐसा नहीं कर सकते हैं यह एक बार ऑपरेशन है, आप अपनी प्रक्रिया को 2 चरणों में तोड़ सकते हैं। सबसे पहले भारी उठाना और परिणामों को एक नई तालिका में स्टोर करें, फिर उस तालिका से पढ़ें और अंतिम अपडेट करें। मुझे हाल ही में कुछ बड़े पैमाने पर डेटा एकत्रीकरण करना पड़ा, और सभी भारी उठाने में प्रसंस्करण और गणना के 2 दिन लगे। परिणाम एक संबंधित तालिका आईडी और अंतिम कुल के साथ एक नई तालिका में डाल दिया गया था। उत्पादन में तब मेरे पास एक त्वरित स्क्रिप्ट थी जो उस नई तालिका से पढ़ी गई और संबंधित पंक्तियों को अपडेट किया गया। यह भी मुझे रोकने और जहां से मैंने छोड़ा था से पुनः आरंभ, और उत्पादन अद्यतन से पहले परिणाम पूर्व जांच करने के लिए अनुमति दी। इसके अलावा, यह वास्तव में तेजी से अद्यतन अद्यतन किया।

ऐसा करने के दौरान, मैंने यह भी सीखा है कि यदि आप कर सकते हैं तो बैच में अपना काम करना महत्वपूर्ण है, और जितनी बार संभव हो सके/लेनदेन को प्रतिबद्ध करते हैं, इसलिए आप बहुत लंबे समय तक बड़े लेनदेन पर नहीं जा रहे हैं ।

संबंधित मुद्दे