2012-01-06 10 views
6

मेरे पास सी # में लिखा गया एक विंडोज़ एप्लिकेशन है जिसे डेटाबेस से 250,000 पंक्तियों को लोड करने की आवश्यकता है और "जैसे ही आप टाइप करते हैं" सुविधा प्रदान करते हैं जिसका अर्थ है जैसे उपयोगकर्ता टेक्स्ट में कुछ टाइप करता है बॉक्स, एप्लिकेशन को like का उपयोग करके सभी 250,000 रिकॉर्ड्स (जो बीटीडब्ल्यू, प्रत्येक पंक्ति 1000 वर्णों वाला सिंगल कॉलम) खोजना चाहते हैं और पाए गए रिकॉर्ड्स प्रदर्शित करते हैं।बड़े ग्रंथों की विशाल सूची खोजने के लिए सबसे तेज़ तरीका

दृष्टिकोण मैं पीछा किया गया था:

आवेदन भार 1- सब एक टाइप किया List<EmployeeData>

while (objSQLReader.Read()) 
{ 
    lstEmployees.Add(new EmployeesData(
     Convert.ToInt32(objSQLReader.GetString(0)), 
     objSQLReader.GetString(1), 
     objSQLReader.GetString(2))); 
} 

2- TextChanged घटना में में रिकॉर्ड, LINQ का उपयोग करना, मैं खोज (नियमित अभिव्यक्ति के संयोजन के साथ) और IEnumerable<EmployeesData> को एक सूची दृश्य में संलग्न करें जो वर्चुअल मोड में है।

String strPattern = "(?=.*wood*)(?=.*james*)"; 
    IEnumerable<EmployeesData> lstFoundItems = from objEmployee in lstEmployees 
    where Regex.IsMatch(Employee.SearchStr, strPattern, RegexOptions.IgnoreCase) 
    select objEmployee; 
    lstFoundEmployees = lstFoundItems; 

3- पुनर्प्राप्तिवर्तनीय इटिम घटना आइटम को प्रदर्शित करने के लिए ListView में आइटम प्रदर्शित करने के लिए संभाली जाती है।

e.Item = new ListViewItem(new String[] { 
    lstFoundEmployees.ElementAt(e.ItemIndex).DateProjectTaskClient, 
    e.ItemIndex.ToString() }); 

हालांकि lstEmployees एसक्यूएल सर्वर से सूची लोड करने, TextChanged पर खोज करने के लिए के लिए अपेक्षाकृत तेज (1.5 सेकंड) भरी हुई है, यह LINQ का उपयोग कर खोज करने के लिए 7 से अधिक मिनट लगते हैं। LIKE खोज करके सीधे SQL सर्वर के माध्यम से खोज 7 सेकंड से कम समय लेता है।

क्या मैं गलत यहाँ कर रहा हूँ? मैं इस खोज को तेज़ी से कैसे बना सकता हूं (अधिक 2 सेकंड नहीं)? यह मेरे ग्राहक से एक आवश्यकता है। तो, किसी भी मदद की अत्यधिक सराहना की है। कृपया मदद करें ...

+0

@RamiShareef, मैं यह मानता हूं कि यह प्रश्न नियमित अभिव्यक्तियों के बारे में है, (वास्तव में किसी भी चीज़ से अधिक), इसलिए कृपया रेगेक्स टैग को न हटाएं। –

+0

क्या आपको इसे स्वत: पूर्ण टेक्स्टबॉक्स की तरह चाहिए? – JayOnDotNet

+0

हाँ .. एक स्वत: पूर्ण टेक्स्ट बॉक्स की तरह, लेकिन परिणामों को एक सूची बॉक्स या सूचीदृश्य में अलग-अलग प्रदर्शित किया जाना चाहिए ... – user1130862

उत्तर

2

this question पर मेरा उत्तर देखें। यदि आपको तत्काल प्रतिक्रिया की आवश्यकता है (यानी उपयोगकर्ता प्रकार के रूप में तेज़ी से), डेटा को स्मृति में लोड करना एक बहुत ही आकर्षक विकल्प हो सकता है। यह थोड़ी मेमोरी का उपयोग कर सकता है, लेकिन यह बहुत तेज़ है।

हालांकि कई पात्र हैं (250 के रिकॉर्ड * 1000), कितने अद्वितीय मान हैं? उन चाबियों से मेल खाने वाले रिकॉर्ड के लिए पॉइंटर्स के साथ चाबियों के आधार पर एक इन-मेमोरी स्ट्रक्चर वास्तव में उन चाबियों के क्रमिक क्रम के लिए जिम्मेदार नहीं है।

यदि डेटा वास्तव में स्मृति में फिट नहीं होगा या अक्सर बदलता है, तो इसे डेटाबेस में रखें और SQL सर्वर पूर्ण टेक्स्ट इंडेक्सिंग का उपयोग करें, जो LIKE से अधिक बेहतर खोजों को संभालेगा। यह एप्लिकेशन से डेटाबेस में एक तेज कनेक्शन मानता है।

पूर्ण टेक्स्ट इंडेक्सिंग ऑपरेटरों/अभिव्यक्तियों का एक शक्तिशाली सेट प्रदान करता है जिसका उपयोग खोजों को और अधिक बुद्धिमान बनाने के लिए किया जा सकता है। यह मुफ्त एसक्यूएल अभिव्यक्ति संस्करण के साथ उपलब्ध है, जो 10 जीबी डेटा तक संभाल लेगा।

0

यदि रिकॉर्ड्स को सॉर्ट किया जा सकता है, तो आप एक बाइनरी खोज के साथ जाना चाह सकते हैं, जो कि बड़े डेटा सेट के लिए बहुत तेज़ है। .NET संग्रह में कई कार्यान्वयन हैं, जैसे List<T> और Array

2

आप चीजों को पहले से लोड और अपने आप डेटा संरचना का निर्माण करने के लिए इच्छुक होगी एक trie

a trie, waht else?

यह स्मृति गहन है कहा जाता है, लेकिन यह क्या डॉक्टर इस मामले में आदेश दिया है।

+0

मुझे नहीं पता कि आप इसे महसूस करते हैं या नहीं, लेकिन ओपी में खोजने के लिए 250.000.000 वर्ण हैं, और एक वस्तु है। नेट लगभग 32 बाइट न्यूनतम है। –

+0

+1 - यह वास्तव में संरचना का प्रकार है जिसके बारे में मैं बात कर रहा हूं। –

+0

@ माइकनाकिस ... सबसे पहले, मुझे संदेह है कि प्रत्येक ओपी 250,000 रिकॉर्ड लंबाई में 1,000 वर्ण नहीं है: औसत लंबाई काफी कम है। दूसरा, आप कोशिशों पर पढ़ना चाहेंगे। (सेडगविक के _ एल्गोरिदम_ (http://algs4.cs.princeton.edu/home/) आज़माएं। त्रिभुज प्रतिनिधित्व को संपीड़ित करने के लिए कई दृष्टिकोण भी हैं: एसीएम लाइब्रेरी की खोज शायद सार्थक है। यहां एक ऐसा दृष्टिकोण है, _Tightly पैक किए गए प्रयास: बड़े मॉडल को मेमोरी में कैसे फ़िट करें, और उन्हें तेज़ लोड करें, Too_ (http://www.aclweb.org/anthology/W/W09/W09-1505.pdf)। –

3

क्या डेटा कॉलम जो डेटा डेटा संग्रहीत करता है उस पर एक सूचकांक है? यदि ऐसा है, तो trie structure जैसा कुछ निकला है जो निकोलस वर्णित है पहले से ही उपयोग में है। SQL सर्वर में इंडेक्स B+ trees का उपयोग करके कार्यान्वित किए जाते हैं, जिनमें एन के लॉग बेस 2 के क्रम में औसत खोज समय होता है, जहां n पेड़ की ऊंचाई होती है। इसका मतलब यह है कि यदि आपके पास तालिका में 250,000 रिकॉर्ड हैं तो खोज के लिए आवश्यक संचालन की संख्या लॉग बेस 2 (250,000) या लगभग 18 ऑपरेशन हैं।

जब आप सभी जानकारी डेटा रीडर में लोड करते हैं और फिर LINQ अभिव्यक्ति का उपयोग करते हैं तो यह एक रैखिक ऑपरेशन होता है, (ओ) एन, जहां एन सूची की लंबाई है। इतना बुरा मामला, यह 250,000 संचालन होने जा रहा है। यदि आप डेटाव्यू का उपयोग करते हैं तो वहां इंडेक्स होंगे जिनका उपयोग खोज में मदद के लिए किया जा सकता है, जो प्रदर्शन में काफी सुधार करेगा।

दिन के अंत में यदि डेटाबेस सर्वर के खिलाफ सबमिट किए गए बहुत से अनुरोध नहीं होंगे तो ऐसा करने के लिए क्वेरी ऑप्टिमाइज़र का लाभ उठाएं। जब तक LIKE ऑपरेशन स्ट्रिंग के सामने वाइल्डकार्ड के साथ नहीं किया जाता है (यानी LIKE %some_string) (इंडेक्स के उपयोग को अस्वीकार करता है) और तालिका पर एक इंडेक्स है जो आपके पास वास्तव में तेज़ प्रदर्शन होगा। यदि डेटाबेस सर्वर पर बहुत सारे अनुरोध सबमिट किए जाएंगे, तो सभी जानकारी को डेटाव्यू में डाल दें ताकि एक इंडेक्स का उपयोग किया जा सके, या ऊपर दिए गए टिम के रूप में एक शब्दकोश का उपयोग करें, जिसमें ओ (1 का खोज समय है)) (एक के आदेश पर), मानते हुए कि एक हैश तालिका का उपयोग करके शब्दकोश लागू किया गया है।

+0

प्रतिक्रिया के लिए धन्यवाद। मुझे LIKE क्वेरीज़ पर% शब्द% का उपयोग करना होगा पाठ जो मैं खोज रहा हूं वह लक्ष्य स्ट्रिंग में कहीं भी हो सकता है। – user1130862

+0

यदि आप डब्ल्यू के साथ शब्द को उपसर्ग करते हैं ild कार्ड सूचकांक का उपयोग नहीं किया जा रहा है; यह केवल तभी काम करेगा जब वाइल्ड कार्ड अंत में है। आम तौर पर नाम खोजों के साथ, खासकर जब आप किसी व्यक्ति के नाम के बारे में बात कर रहे हैं तो आप मान सकते हैं कि उपयोगकर्ता पहले कुछ अक्षर जानेंगे। मुझे लगता है कि इस मामले में ऑटो-पूर्ण नियंत्रण के साथ आप और भी स्वीकार्य हैं जिसका आप वर्णन कर रहे हैं। मैं मध्य व्यक्ति में किसी व्यक्ति का नाम टाइप करना शुरू नहीं कर रहा हूं? –

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

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