2008-12-05 13 views
24

मेरी साइट पर डीबी लोड वास्तव में उच्च हो रहा है, इसलिए मेरे लिए सामान्य प्रश्नों को कैश करने का समय है जिसे कई बार एक घंटे कहा जाता है जहां परिणाम नहीं बदल रहे हैं। तो मेरे शहर मॉडल पर उदाहरण के लिए मैं निम्न कार्य करें:रेल कैशिंग डीबी क्वेरीज और सर्वोत्तम अभ्यास

def self.fetch(id) 
    Rails.cache.fetch("city_#{id}") { City.find(id) } 
end 

def after_save 
    Rails.cache.delete("city_#{self.id}") 
end 

def after_destroy 
    Rails.cache.delete("city_#{self.id}") 
end 

तो अब जब मैं (1) पहली बार मैं डीबी लेकिन अगले 1000 बार मैं स्मृति से परिणाम प्राप्त मारा City.find कर सकते हैं। महान। लेकिन शहर में अधिकांश कॉल सिटी नहीं हैं। 1 (लेकिन) @ user.city.name जहां रेल्स fetch का उपयोग नहीं करता है लेकिन फिर डीबी से पूछताछ करता है ... जो समझ में आता है लेकिन वास्तव में मैं इसे नहीं करना चाहता हूं।

मैं सिटी.फिंड (@ user.city_id) कर सकता हूं लेकिन वह बदसूरत है।

तो मेरे लिए आपका प्रश्न है। स्मार्ट लोग क्या कर रहे हैं? यह करने का सही तरीका क्या है?

उत्तर

-1

चेक बाहर cached_model

+0

Memoization सिर्फ Rails.cache लपेटता पर कुछ अच्छा लेख है। मुझे नहीं लगता कि यह मॉडल एसोसिएशन की मदद करेगा जैसे आप ढूंढ रहे हैं। – Bill

+1

ज्ञापन रेल कैश को लपेटता नहीं है। Rails.cache आमतौर पर प्रक्रियाओं के बीच साझा कैश स्टोर होता है (जैसे कि आप वास्तव में कैशिंग लाभ प्राप्त करते हैं)। ज्ञापन केवल वर्तमान प्रक्रिया के भीतर होता है। – Michael

0

मैं आगे जाना है और Memoization पर एक नज़र है, जो रेल 2.2 में है ले जाएगा।

"Memoization एक विधि आरंभ एक बार और फिर अपने मूल्य दोहराने उपयोग के लिए दूर stashing की एक पद्धति है।"

हाल ही में एक शानदार Railscast episode था जो आपको ऊपर उठाने और अच्छी तरह से चलने वाला होना चाहिए। Railscast से

त्वरित कोड नमूना:

class Product < ActiveRecord::Base 
    extend ActiveSupport::Memoizable 

    belongs_to :category 

    def filesize(num = 1) 
    # some expensive operation 
    sleep 2 
    12345789 * num 
    end 
    memoize :filesize 
end 

More on Memoization

+0

Rails.cache पर ज्ञापन का लाभ क्या है और यह User.city.name की समस्या का समाधान कैसे करता है जहां रेल कैश किए गए डेटा का उपयोग करने के बजाय शहर पर एक खोज करता है? –

+9

ज्ञापन केवल प्रति सर्वर प्रक्रिया के आधार पर परिणाम संग्रहीत करेगा और यह अमान्य नहीं है, क्योंकि यह आपकी स्थिति के लिए अपेक्षाकृत अनुचित है और इसका उपयोग इस तरह से नहीं किया जाना है। – Michael

23

कैशिंग, नाबालिग अंक की एक जोड़ी के संबंध में:

यह ऑब्जेक्ट प्रकार और आईडी के अलग होने के लिए स्लैश का उपयोग कर के लायक है , जो रेल सम्मेलन है। इससे भी बेहतर, ActiveRecord मॉडल cacke_key इंस्टेंस विधि प्रदान करते हैं जो तालिका नाम और आईडी, "शहरों/13" आदि का एक अद्वितीय पहचानकर्ता प्रदान करेगा।

आपके बाद के फ़िल्टर में एक मामूली सुधार। चूंकि आपके पास डेटा है, इसलिए आप इसे कैश पर वापस लिख सकते हैं क्योंकि इसे हटाने के विरोध में।

    : यही कारण है कि आप डेटाबेस के लिए एक यात्रा के बचत है)

     
    def after_save 
        Rails.cache.write(cache_key,self) 
    end 
    

    सवाल की जड़ तक के रूप में, यदि आप लगातार @ user.city.name खींच रहे, वहाँ दो असली विकल्प हैं

  • उपयोगकर्ता के शहर का नाम उपयोगकर्ता पंक्ति में denormalize। @ user.city_name (city_id विदेशी कुंजी रखें)। यह मान सहेजने के समय पर लिखा जाना चाहिए।

-या-

  • उत्सुक लोड करने के लिए अपने User.fetch विधि शहर को लागू करें। केवल तभी ऐसा करें जब शहर की पंक्ति कभी भी नहीं बदलती (यानी नाम इत्यादि), अन्यथा आप संभावित रूप से कैश अमान्यता के संबंध में कीड़े का एक खोल खोल सकते हैं।

व्यक्तिगत राय: बुनियादी आधारित विधियों लाने आईडी लागू (या एक प्लगइन का उपयोग) memcached के साथ एकीकृत करने, और उपयोगकर्ता की पंक्ति में शहर का नाम denormalize।

मैं व्यक्तिगत रूप से कैश मॉडल शैली प्लगइन का एक बड़ा प्रशंसक नहीं हूं, मैंने कभी ऐसा नहीं देखा है जिसने विकास की एक महत्वपूर्ण मात्रा को बचाया है जिसे मैंने जल्दबाजी में नहीं उगाया है।

यदि आप बहुत से डेटाबेस प्रश्नों को प्राप्त कर रहे हैं तो यह निश्चित रूप से उत्सुक लोडिंग (माध्यम: शामिल) की जांच करने के लायक है यदि आप पहले से नहीं हैं। डाटाबेस क्वेरीज की मात्रा को कम करने के लिए यह पहला कदम होना चाहिए।

+1

ईजी 'उपयोगकर्ता। कहीं (आईडी: 3)। शामिल (: शहर)। पहला '। बहुत से लोगों के लिए कई रिश्तेदारों में बहुत से लोगों के लिए 'विलय-विलय' की सराहना की गई है। ईजी 'City.joins (: रेस्तरां) .merge (user.favorite_restaurants)', उन सभी शहरों को वापस कर देगा जहां उपयोगकर्ता के पास कई पसंदीदा रेस्तरां हैं, और रेस्तरां में कई शहर हैं। चेक करें [शामिल और जुड़ता है] (http://guides.rubyonrails.org/active_record_querying.html#joining-tables)। कैशिंग के दर्द से गुजरने के बजाय शक्तिशाली प्रश्नों के साथ कॉल को काटना सीखने के लिए निश्चित रूप से सार्थक। –

0

यदि आपको डेटा पर SQL क्वेरी को तेज़ करने की आवश्यकता है जो समय के साथ अधिक नहीं बदलता है तो आप भौतिक दृश्यों का उपयोग कर सकते हैं।

एक मैटव्यू एक प्रश्न के परिणामों को की तालिका-जैसी संरचना में संग्रहीत करता है, जिससे डेटा पूछताछ की जा सकती है। जोड़ने या पंक्तियों को हटाने के लिए संभव नहीं है, लेकिन शेष समय यह वास्तविक तालिका की तरह व्यवहार करता है। प्रश्न तेजी से हैं, और मैटव्यू स्वयं अनुक्रमित हो सकता है।

इस लेखन के समय, ओरेकल डीबी, पोस्टग्रेएसक्यूएल, साइबेस, आईबीएम डीबी 2, और माइक्रोसॉफ्ट एसक्यूएल सर्वर में मैटव्यू मूल रूप से उपलब्ध हैं। दुर्भाग्यवश, MySQL मैटव्यू के लिए मूल समर्थन प्रदान नहीं करता है, लेकिन इसके लिए ओपन सोर्स विकल्प हैं।

यहाँ कैसे रेल

में matviews उपयोग करने के लिए

sitepoint.com/speed-up-with-materialized-views-on-postgresql-and-rails

hashrocket.com/materialized-view-strategies-using-postgresql

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