2012-07-29 11 views
8

में क्वेरी परिणाम कैसे संग्रहीत किए जाते हैं जब मैंने डेटाबेस में कोई प्रश्न किया और परिणामों को mysqli_result में पुनर्प्राप्त किया, तो स्मृति उपयोग बहुत छोटा है। हालांकि, जब मैं क्वेरी परिणामों में सभी पंक्तियों को एक सहयोगी सरणी में लाता हूं, तो स्मृति उपयोग बहुत अधिक हो जाता है।PHP: mysqli_result

<?php 
    require_once("../config.php"); //db connection config 
    $db = new mysqli(DB_HOST,DB_USER,DB_PASSWORD,DB_DBASE); 

    $query ="select * from table_name"; 
    if($r = $db->query($query)){ 
    echo "MEMORY USAGE before : ". memory_get_usage()."<br><br>"; 
    $rows = array(); 
    while($row = $r->fetch_assoc()){ 

     $rows[]= $row; 
    } 
    echo "MEMORY USAGE after : ". memory_get_usage()."<br><br>"; 


    //before: 660880 
    //after: 114655768 
    // # of records: around 30 thousands 
?> 

यह मेरे लिए समझ में आता है कि इस सारे परिणाम भंडारण बहुत स्मृति लेने वाली है, लेकिन मैं अभी कैसे आ mysqli_result इतना छोटा है सोच रहा हूँ। ऐसा नहीं हो सकता है कि हर बार fetch_assoc कहलाता है जब परिणाम dbase के लिए पूछताछ की जाती है। तो फिर स्मृति में संग्रहीत परिणाम कहां हैं।

+1

मैंने कहीं पढ़ा है कि 'mysql_ *' फ़ंक्शंस सर्वर से सभी परिणाम पंक्तियों को एक साथ लाता है। हालांकि पीडीओ (और संभवतः mysqli) मांग पर प्रत्येक पंक्ति को पुनः प्राप्त करें। इसलिए प्रत्येक कॉल लाने के लिए, आप थोड़ी मेमोरी का उपयोग करने जा रहे हैं। लेकिन आप प्रत्येक पंक्ति को सरणी में संग्रहीत करते हैं, इसलिए यह समझ में आता है कि आपकी मेमोरी उपयोग जमा हो जाएगी। –

+0

क्या आपका मतलब है कि प्रत्येक कॉल लाने के साथ, mysqli परिणाम के लिए डेटाबेस से पूछेगा? – spchuang

+1

मेरी समझ से, जब आप 'क्वेरी()' MySQL कॉल करते हैं तो क्वेरी निष्पादित करता है और सभी परिणाम पंक्तियों को PHP पर वापस करने के लिए तैयार करता है। हालांकि, अगर mysqli पीडीओ (कम से कम पीडीओ का डिफ़ॉल्ट) की तरह है, तो जब तक आप कॉल नहीं करते हैं तब तक पंक्तियां प्राप्त करना शुरू नहीं होगा। जब तक आप 'fetchAll() 'को कॉल नहीं करते हैं, तब तक प्रत्येक पंक्ति एक बार में पुनर्प्राप्त की जाएगी। इसका मतलब है कि आपका मेमोरी उपयोग इसलिए है क्योंकि आपने परिणामों को सरणी में सहेजा है, न कि mysqli के कारण। –

उत्तर

2

परिणाम लाने और संसाधन के लिए सूचक को संग्रहीत करने के बीच एक बड़ा अंतर है।

यदि आप echo $r;memory_get_usage(); पर अपनी पहली कॉल से पहले, आपको पता चलेगा कि यह सिर्फ एक सूचक है। यह आपके परिणाम सेट के सूचक है। जब तक आप fetch अपने परिणाम न दें, परिणाम सेट वास्तव में स्मृति में संग्रहीत नहीं किया जाएगा।

मैं सुझाव दूंगा कि आप जो करने की कोशिश कर रहे हैं उसके लिए fetchAll() चलाएं। इसके परिणामस्वरूप बेहतर प्रदर्शन के साथ आपके सभी परिणामों तक पहुंचने के लिए 1 विधि का परिणाम होगा क्योंकि यह PHP में लूप की बजाय mysqli एक्सटेंशन (सी लाइब्रेरी) पर बंद हो गया है।

आप अपने परिणामों को स्मृति से अपने परिणामों को साफ़ करने के लिए निःशुल्क परिणाम फ़ंक्शन का भी उपयोग कर सकते हैं। यदि आप परिचित हैं तो यह जावा में एक कर्सर बंद करने जैसा है।

+0

धन्यवाद। यह बहुत उपयोगी है! :) – spchuang

+0

तो संसाधन वास्तव में स्मृति उपयोग में क्यों नहीं जोड़ा गया है?संसाधन मेमोरी स्पेस का उपयोग कर रहा है ... या यह डिस्क या कुछ लिखा गया है? –

+0

फ़ेच कॉल करने से पहले '$ r' echo'ing करके, MySQL क्वेरी परिणामों के लिए आवंटित स्थान होगा, लेकिन PHP नहीं। जब आप फ़ेच कॉल करते हैं तो PHP केवल परिणामों की मेमोरी स्पेस को परिणाम देगा। –

1

मैं इस के बजाय करने के लिए लगता है कि तुम चाहिए:

while($row = $r->fetch_assoc()){ 
    //Do whatever you need with the record, then: 
    unset($row); 
} 

जिस तरह से आप पोस्ट $rows में एक विशाल सरणी सभा है, और स्मृति के उपयोग कि पता चलता है।

+0

मुझे पता है कि आपका क्या मतलब है और यह निश्चित रूप से fetch_assoc() के लिए मूल मंशा है। समस्या यह है कि मैं परिणाम लाने के लिए जा रहा हूं और इसके साथ कुछ कर रहा हूं और रिकॉर्ड प्रदर्शित करने के लिए इसे (एमवीसी अर्थ में) देखने के लिए पास कर रहा हूं। मुझे लगता है कि मैं अपना कार्यान्वयन बदल सकता हूं ताकि एक समय में एक रिकॉर्ड देखने के लिए पारित किया जा सके। – spchuang

+0

यह बुद्धिमान होगा :) – Niloct

+0

धन्यवाद। यह एक समस्या है क्योंकि मैं सीधे मॉडल के साथ संवाद करने से बचने की कोशिश कर रहा हूं, इसलिए मेरे पास डेटा पास करने के बीच में एक नियंत्रक भी है। मुझे क्या करना है, प्रत्येक रिकॉर्ड को प्रदर्शित करने के लिए वास्तव में छोटे दृश्य टेम्पलेट को बनाना है ... – spchuang