2011-08-31 16 views
12

का उपयोग करते हैं, तो स्मृति में क्या होता है, मैं mysql_query का उपयोग करके बड़ी मात्रा में डेटा लाने के लिए उपयोग करता था, फिर डेटा को संसाधित करने के लिए परिणामस्वरूप एक-एक करके परिणाम देता था। उदाहरण के लिए:PHP में, जब हम mysql_query

$mysql_result = mysql_query("select * from user"); 
while($row = mysql_fetch_array($mysql_result)){ 
    echo $row['email'] . "\n"; 
} 

हाल ही में मैं कुछ ढांचे को देखा और महसूस किया कि वे स्मृति और सरणी लौटने में एक सरणी के लिए सभी डेटा दिलवाया।

$large_array = $db->fetchAll("select * from user"); 
foreach($large_array as $user){ 
    echo $user['email'] . "\n"; 
} 

मैं प्रत्येक विधि के पेशेवरों/विपक्ष को जानना चाहता हूं। ऐसा लगता है कि स्मृति में सबकुछ लोड करना आपदाओं के लिए एक नुस्खा है यदि आपके पास वस्तुओं की एक लंबी सूची है। लेकिन फिर, एक सहकर्मी ने मुझे बताया कि MySQL ड्राइवर को परिणाम को स्मृति में वैसे भी सेट करना होगा। मैं किसी ऐसे व्यक्ति की राय लेना चाहता हूं जो समझता है कि सवाल प्रदर्शन के बारे में है। कृपया कोड पर टिप्पणी न करें, मैंने इसे पोस्ट के लिए एक उदाहरण के रूप में बनाया है।

धन्यवाद

+0

क्यों न स्वयं को कोशिश करें? –

+2

इसके विपरीत, http://www.php.net/manual/en/function.mysql-unbuffered-query.php पर देखें। – deceze

उत्तर

1

यह सच है कि MySQL लाइब्रेरी "सामान्यतः" क्लाइंट मेमोरी में सभी डेटा लाती है।यह आमतौर पर mysql_store_result() का उपयोग कर ऐसा करता है। LIMIT कीवर्ड के साथ ऊपर दिखाए गए अनुसार आप बहुत बड़े प्रश्नों को विभाजित कर सकते हैं, लेकिन जोखिम यह है कि डेटा असंगत हो जाता है क्योंकि वे बीच में बदल सकते हैं। आप ताले का उपयोग कर इसकी देखभाल कर सकते हैं।

एक और दृष्टिकोण mysql_use_result() का उपयोग करने के लिए किया जा सकता है, जो सर्वर-साइड पर अधिक संसाधनों का उपयोग करता है और लाने के लिए ASAP को पूरा करने की आवश्यकता होती है।

+0

ऐन लिंक ज़ुर Englischen MySQL Dokumentation wäre glaube ich angebrachter। : ओ) – deceze

+0

ओप, क्षमा करें, उत्तेजना। मैंने इसे अभी बदल दिया है ताकि आप सभी इससे लाभ उठा सकें :-) – glglgl

+0

= बहुत अच्छे बिंदु के बीच डेटा परिवर्तन! – U0001

-2

बस कुछ मैंने सीखा है जब यह प्रदर्शन की बात आती है: foreach एक while पाश की तुलना में तेजी है। शायद आपको प्रत्येक के अपने परिणामों को बेंचमार्क करना चाहिए और देखें कि कौन सा तेज और कम स्मृति गहन है। आईएमएचओ, मुझे बाद के दृष्टिकोण को बेहतर पसंद है। लेकिन क्या आपको वास्तव में उपयोगकर्ता तालिका के भीतर प्रत्येक कॉलम की आवश्यकता है? यदि नहीं, तो उन सभी को पकड़ने के लिए * का उपयोग करने के बजाय आपको आवश्यक कॉलम को परिभाषित करने के बजाय। चूंकि यह स्मृति और गति के साथ भी मदद करेगा।

+4

ओएमजी फोरैच थोड़ी देर से तेज है –

+0

हां, डेटा के बड़े सरणी से निपटने पर, 'while' loops' के बजाय संभव होने पर 'foreach' का उपयोग करें। http://juliusbeckmann.de/blog/php-foreach-vs-while-vs-for-the-loop-battle.html यह समय और समय साबित हुआ है ... – SoLoGHoST

+3

सवाल फोरच बनाम समय के बारे में नहीं है। और इस तरह की तुलना बेकार है: आप 12sec sql क्वेरी निष्पादित करते हैं लेकिन आप 0.1 सेकंड लूप को अनुकूलित करने का प्रयास कर रहे हैं ... –

4

आप मामलों को मिश्रित कर रहे हैं।

  • प्रयोज्य, जो आपके कोड रास्ता सरणियों
  • और unoptimized एल्गोरिथ्म, जब अनुभवहीन प्रोग्रामर बजाय सभी गणना करने या भागों में डेटा प्राप्त करने के डेटाबेस बनाने की स्क्रिप्ट में सभी डेटा लोड करने के लिए करते हैं के साथ चिकनी बनाता है।

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

कृपया यह भी ध्यान दें कि फ्रेमवर्क डेटाबेस लूप के अंदर डेटा को प्रतिबिंबित करने जैसी ऐसी चीजें कभी नहीं करेंगे।
प्रत्येक अच्छी ढांचा आउटपुट चीजों के लिए एक टेम्पलेट का उपयोग करेगा, और इस मामले में एक सरणी बेहद आसान हो जाएगी।

+0

धन्यवाद कर्नल श्रापनेल। पुन: गूंजते हुए, यह चित्रण करने के लिए सिर्फ एक उदाहरण था। – U0001

2

जब बड़े परिणाम सेट के साथ काम कर, मैं आमतौर पर, बैचों के माध्यम से जाना इस तरह:

$current = 0; 
$batchSize = 1000; 

while (true) { 
    $large_array = $db->fetchAll(sprintf("select * from user limit %s, %s", $current, $batchSize)); 
    if (sizeof($large_array) == 0) { 
    break; 
    } 

    $current += sizeof($large_array); 
    foreach($large_array as $user){ 
    echo $user['email'] . "\n"; 
    } 
} 

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

वैसे, एक स्क्रिप्ट स्थापित करके अपेक्षाकृत आसान है कि दोनों स्निपेट्स के समय (और चोटी मेमोरी) को मापें। मैं दांव दूंगा कि वे उस समय में अलग नहीं होंगे।

+0

लूप के दौरान केवल एक क्यों नहीं बनाना है? –

+0

हां, मैं खुद का परीक्षण कर सकता था लेकिन मैं आलसी हूं। और मैं इसके बारे में पेशेवर राय के बारे में और भी उत्सुक हूं। उदाहरण के लिए, यहां कुछ लोगों ने विभिन्न दृष्टिकोण प्रस्तुत किए हैं और उन्हें समझाया है। यह मेरे लिए, एक परीक्षण से बेहतर है। – U0001

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