2012-01-04 8 views
5

मुझे अपने iOS एप्लिकेशन में SQLite का उपयोग कर रहा हूँ और मैं बचत/लोड हो रहा है की एक बहुत कुछ है, जबकि उपयोगकर्ता यूआई के साथ बातचीत कर रहा है क्या करना है। यह एक समस्या है क्योंकि यह यूआई को बहुत ही कमजोर और धीमी बनाती है।आईओएस SQLite धीरे प्रदर्शन

मैं एक अतिरिक्त धागा में परिचालन कर रही है की कोशिश की है लेकिन मुझे नहीं लगता इस SQLite में संभव है। मुझे त्रुटि कोड SQLITE_BUSY और SQLITE_LOCKED अक्सर मिलता है यदि मैं ऐसा करता हूं।

क्या उन त्रुटि कोडों के बिना मल्टीथ्रेडिंग में ऐसा करने का कोई तरीका है, या क्या मुझे SQLite को छोड़ देना चाहिए?

+1

क्या आपने अपने द्वारा उपयोग किए जाने वाले प्रश्नों को ट्यून करने का प्रयास किया है और यह देखने के लिए क्वेरी योजनाओं को देख रहे हैं कि कोई अनुक्रमणिका आवश्यक है या नहीं? –

+2

क्या आप कई लिखते समय लेनदेन का उपयोग कर रहे हैं? आपको करना चाहिए - यह एक बड़ा अंतर बनाता है। –

+0

फ्रेडरिक चेंग: मैं एकाधिक लेखन का उपयोग कर रहा हूं और पुनर्प्राप्त करता हूं। मैं देख रहा हूं कि इंडेक्सिंग मदद करेगी, लेकिन इसमें बहुत सारे रिकॉर्ड डालने के लिए हैं, इसलिए मुझे नहीं लगता कि इंडेक्सिंग मदद करेगी। हॉट लिक्स: एकाधिक लेखन का उपयोग करते समय मैं लेनदेन नहीं कर रहा हूं। क्या मुझे एक ही लॉक का उपयोग कर डेटाबेस में हर लिखने के लिए ऐसा करना चाहिए? – VTS12

उत्तर

0

SQLite को न छोड़ें। धीमे होने से बचने के लिए आप UI थ्रेड से अलग थ्रेड में निश्चित रूप से ऐसा कर सकते हैं। बस सुनिश्चित करें कि केवल एक थ्रेड एक समय में डेटाबेस तक पहुंच रहा है। समवर्ती पहुंच से निपटने के दौरान SQLite बहुत अच्छा नहीं है।

+1

समवर्ती _reads_ के लिए यह ठीक है, लेकिन _updates_ अन्य सभी को लॉक करें (डीबी-स्तर लॉकिंग से बेहतर कुछ भी की जटिलता के कारण)। –

+0

मेरी समस्या यह है कि जब उपयोगकर्ता डेटा एक्सेस/लिखता है तो मैं नियंत्रित नहीं कर सकता। उदाहरण के लिए, एक दृश्य पर यह डेटा को पढ़ और सहेज लेगा, लेकिन फिर वे विवरण क्लिक कर सकते हैं और एक नया दृश्य दबा सकते हैं जो डेटा को पढ़ने/लिखना भी चाहेंगे। सुनिश्चित नहीं है कि मैं कैसे सुनिश्चित कर सकता हूं कि एक थ्रेड एक ही समय में डेटाबेस तक पहुंचता है। – VTS12

3

यह पूरी तरह से संभव है, तो आप सिर्फ अपनी पृष्ठभूमि सूत्र में SQLite के लिए उपयोग serialise की जरूरत है।

this recent question पर मेरा उत्तर आपको सही दिशा में इंगित करना चाहिए।

जैसा कि कहीं और बताया गया है, SQLite समवर्ती पढ़ने के लिए ठीक है, लेकिन लिखने के लिए डेटाबेस स्तर पर ताले। इसका मतलब है कि यदि आप अलग-अलग धागे में पढ़ रहे हैं और लिख रहे हैं, तो आपको SQLITE_BUSY और SQLITE_LOCKED त्रुटियां मिलेंगी।

इस से बचने के लिए सबसे बुनियादी तरीका serialise करने के लिए सभी डीबी एक्सेस (रीड और राईट) या तो एक प्रेषण कतार या एक NSOperationQueue के रूप में इस का उपयोग मुख्य थ्रेड पर जगह नहीं ले रही है 1. की एक संगामिति है कि में है , आपका यूआई प्रभावित नहीं होगा।

यह स्पष्ट रूप से ओवरलैपिंग को पढ़ और लिखना बंद कर देगा, लेकिन यह एक साथ पढ़ने को भी रोक देगा। यह स्पष्ट नहीं है कि यह एक प्रदर्शन हिट है जिसे आप ले सकते हैं या नहीं।

NSOperationQueue *backgroundQueue = [[NSOperationQueue alloc] init]; 

[backgroundQueue setMaxConcurrentOperationCount:1]; 

तो फिर तुम बस के रूप में आप फिट देख कतार में आपरेशन जोड़ सकते हैं:

जैसा कि ऊपर वर्णित एक कतार आरंभ करने के लिए।

+0

मैंने इसे इस तरह से करने की कोशिश की और अभी भी त्रुटियों का अनुभव किया। अब मैं एक प्रेषण कतार का उपयोग कर रहा हूँ। – VTS12

+0

क्या आपके पास अब सब ठीक से काम कर रहा है? एक प्रेषण कतार भी ठीक होना चाहिए। – paulbailey

+0

नहीं, प्रेषण कतार का उपयोग करने के बाद, मुझे लगातार SQLITE_BUSY और SQLITE_LOCKED त्रुटि कोड मिल रहे हैं। इसके अलावा अजीब व्यवहार जैसे विचारों को जल्दी से पॉप किया जा रहा है। – VTS12

0

बंद:

आप चेकआउट है: FMDB यह एक SQLite आवरण है और धागा सुरक्षित है। मैंने इसे अपने सभी स्क्लाइट प्रोजेक्ट में इस्तेमाल किया।

0

मैं कोर डेटा का उपयोग करने की सलाह देता हूं जो स्क्लाइट के शीर्ष पर बैठता है। मैं इसे एक बहुप्रचारित वातावरण में उपयोग करता हूं। यहां Concurrency with Core Data पर एक मार्गदर्शिका दी गई है।

2

समर्पित SQLite थ्रेड में सब कुछ होने के बाद, या एक-ऑप-ऑन-ए-टाइम ऑपरेशन कतार बहुत अच्छे समाधान हैं, खासकर अपने जिटर यू को हल करने के लिए। एक और तकनीक (जो झटके में मदद नहीं कर सकती है) उन त्रुटि कोडों को खोजना है, और बस लूप, अपडेट को फिर से प्रयास करना जब तक कि आपको एक सफल रिटर्न कोड न मिल जाए।

1

SQLite को WAL मोड में रखें। फिर पढ़ा जाएगा अवरुद्ध नहीं किया जाएगा। ऐसा नहीं लिखता - आपको उन्हें क्रमबद्ध करने की आवश्यकता है। इसे हासिल करने के कई तरीके हैं। उनमें से एक SQLite द्वारा प्रदान किया जाता है - डब्ल्यूएएल हुक का उपयोग यह संकेत करने के लिए किया जा सकता है कि अगला लेखन शुरू हो सकता है।

डब्ल्यूएएल मोड आमतौर पर आपके ऐप के प्रदर्शन में सुधार करना चाहिए। ज्यादातर चीजें थोड़ा तेज हो जाएंगी। पढ़ना बिल्कुल अवरुद्ध नहीं होगा। केवल बड़े लेनदेन (कई एमबी) धीमा हो जाएंगे। आम तौर पर नाटकीय कुछ भी नहीं।

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