मेरे पास एक विशाल तालिका है जिसे मुझे एक निश्चित क्रम पर पढ़ने और कुछ समेकित आंकड़ों की गणना करने की आवश्यकता है। तालिका में पहले से ही सही क्रम के लिए क्लस्टर्ड इंडेक्स है इसलिए रिकॉर्ड प्राप्त करना बहुत तेज़ है। मैं जिस कोड को लिखने की जरूरत है उसे सरल बनाने के लिए LINQ से SQL का उपयोग करने का प्रयास कर रहा हूं। समस्या यह है कि मैं सभी ऑब्जेक्ट्स को मेमोरी में लोड नहीं करना चाहता, क्योंकि डेटाकॉन्टेक्स्ट उन्हें चारों ओर रखना चाहता है - फिर भी उन्हें पेज करने का प्रयास करने से भयानक प्रदर्शन समस्याएं होती हैं।LINQ से SQL के साथ विशाल तालिका पढ़ें: मेमोरी बनाम धीमी पेजिंग
यहां ब्रेकडाउन है। मूल प्रयास किया गया था इस:
var logs =
(from record in dataContext.someTable
where [index is appropriate]
select record);
foreach(linqEntity l in logs)
{
// Do stuff with data from l
}
यह बहुत तेजी से है, और एक अच्छा दर पर धाराओं, लेकिन समस्या यह है कि आवेदन की स्मृति उपयोग ऊपर चलती है कभी नहीं बंद हो जाता है। मेरा अनुमान है कि LINQ से SQL इकाइयों को स्मृति में चारों ओर रखा जा रहा है और ठीक से निपटान नहीं किया जा रहा है। तो Out of memory when creating a lot of objects C# पढ़ने के बाद, मैंने निम्नलिखित दृष्टिकोण की कोशिश की। ऐसा लगता है कि Skip
/Take
प्रतिमान है कि कई लोग स्मृति की बचत की अतिरिक्त सुविधा के साथ उपयोग करते हैं।
ध्यान दें कि _conn
पहले से बनाया गया है, और प्रत्येक क्वेरी के लिए एक अस्थायी डेटा संदर्भ बनाया गया है, जिसके परिणामस्वरूप संबद्ध संस्थाएं कचरा एकत्रित होती हैं।
int skipAmount = 0;
bool finished = false;
while (!finished)
{
// Trick to allow for automatic garbage collection while iterating through the DB
using (var tempDataContext = new MyDataContext(_conn) {CommandTimeout = 600})
{
var query =
(from record in tempDataContext.someTable
where [index is appropriate]
select record);
List<workerLog> logs = query.Skip(skipAmount).Take(BatchSize).ToList();
if (logs.Count == 0)
{
finished = true;
continue;
}
foreach(linqEntity l in logs)
{
// Do stuff with data from l
}
skipAmount += logs.Count;
}
}
अब मेरे पास वांछित व्यवहार है कि डेटा उपयोग के माध्यम से स्मृति उपयोग में वृद्धि नहीं होती है। फिर भी, मेरे पास एक बहुत ही खराब समस्या है: प्रत्येक Skip
डेटा को अधिक से अधिक धीरे-धीरे लोड करने का कारण बन रहा है क्योंकि अंतर्निहित क्वेरी वास्तव में सर्वर को पिछले सभी पृष्ठों के लिए सभी डेटा के माध्यम से जाने का कारण बनती है। क्वेरी चलाने के दौरान प्रत्येक पृष्ठ को लोड करने में लंबा और लंबा समय लगता है, और मैं यह बता सकता हूं कि यह एक वर्गबद्ध संचालन में बदल रहा है। यह समस्या निम्न पदों में दिखाई दिया है:
मैं LINQ के साथ ऐसा करने के लिए एक रास्ता मुझे पेजिंग द्वारा सीमित मेमोरी उपयोग की अनुमति देता है कि खोजने के लिए नहीं कर पा रहे डेटा, और फिर भी अभी भी प्रत्येक पृष्ठ निरंतर समय में लोड होता है। क्या यह ठीक से करने का कोई तरीका है? मेरा झुकाव यह है कि डेटाकॉन्टेक्स्ट को ऊपर दिए गए पहले दृष्टिकोण में वस्तु के बारे में स्पष्ट रूप से भूलने के लिए कुछ तरीका हो सकता है, लेकिन मुझे यह नहीं पता कि यह कैसे किया जाए।
"मेरे पास एक विशाल तालिका है जिसे मुझे एक निश्चित क्रम पर पढ़ने और कुछ समग्र आंकड़ों की गणना करने की आवश्यकता है।" - इसे टीएसक्यूएल में सर्वर पर करें .... यही वह अच्छा है! –
नहीं, आंकड़े उससे अधिक जटिल हैं, और SQL क्वेरी के साथ computable नहीं हैं। डेटा को एक निश्चित क्रम में और फिर अस्थायी रूप से सही, आदि की गणना की जाने वाली चीज़ों की आवश्यकता होती है। –
"नहीं, आंकड़े उससे अधिक जटिल हैं, और SQL क्वेरी के साथ गणना नहीं कर रहे हैं" - वास्तव में? क्या एक पूर्ण उदाहरण देना संभव है? –