سؤال

أواجه بعض المشكلات الخطيرة في وظائف كائن بيانات PHP. أحاول حلقة من خلال مجموعة نتيجة كبيرة (~ 60K الصفوف، ~ 1GIG) باستخدام استعلام مخزن مؤقت لتجنب جلب المجموعة بأكملها.

بغض النظر عن ما أقوم به. إليك التعليمات البرمجية الخاصة بي لإعادة إنتاج المشكلة:

<?php
$Database = new PDO(
    'mysql:host=localhost;port=3306;dbname=mydatabase',
    'root',
    '',
    array(
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
    )
);

$rQuery = $Database->query('SELECT id FROM mytable');

// This is never reached because the result set is too large
echo 'Made it through.';

foreach($rQuery as $aRow) {
    print_r($aRow);
}
?>

إذا قمت بحد الاستعلام مع عدد معقول، فإنه يعمل بشكل جيد:

$rQuery = $Database->query('SELECT id FROM mytable LIMIT 10');

لقد حاولت اللعب باستخدام PDO :: MySQL_ATTR_MAX_BUFFER_SIZE واستخدام PDO :: إعداد () و PDO :: Execute () كذلك (على الرغم من عدم وجود معلمات في الاستعلام أعلاه)، كلاهما دون جدوى. سيكون موضع تقدير أي مساعدة.

هل كانت مفيدة؟

المحلول

إذا فهمت هذا الحق، فإن الاستعلامات المخزنة المخزنة تنطوي على إخبار PHP أنك تريد انتظار مجموعة النتائج بأكملها قبل البدء في المعالجة. قبل شركة تنمية نفط عمان، كان هذا الافتراضي وكان عليك الاتصال mysql_unbuffered_query إذا كنت ترغب في التعامل مع النتائج على الفور.

لماذا لا يتم شرح هذا في صفحة برنامج تشغيل PDO MySQL، وأنا لا أعرف.

نصائح أخرى

يمكنك محاولة تقسيمه إلى قطع غير كافية بما يكفي للتسبب في مشاكل:

<?php    
$id = 0;
$rQuery = $Database->query('SELECT id FROM mytable ORDER BY id ASC LIMIT 100');

do {
    stuff($rQuery);
    $id += 100;
} while ( $rQuery = $Database->query(
            'SELECT id FROM mytable ORDER BY id ASC LIMIT 100 OFFSET '.$id
          )
        );
?>

... تحصل على الفكرة، على أي حال.

أو ربما يمكنك تجربة وظائف MySQL بدلا من ذلك:

while ($row = mysql_fetch_row($query)) {
...
}

والتي ستكون بالتأكيد أسرع، لأن هذا البيان foreach يجعل انطباعا للاستخدام fetchAll() في حين أن fetch() كل صف

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top