Добрый день! Написал скрипт, который выполняет запрос на mysql и преобразует его в xml формат. Проблема в том, что скрипт выполняется очень долго, данные не до конца преобразуются в xml и завершается работа скрипта сообщением о превышении лимита времени. Лимит времени выставил 360 секунд. Запрос в mysql выполняется за 10 секунд. Я так понимаю, что вся загвоздка в преобразовании в xml. Преобразования делаю через DOM. Подскажите, что можно сделать, что бы все преобразовывалось быстро.
Если "через DOM" означает что все данные надо сначала впихнуть в объект, только потом можно что-то сделать.... Короче когда имеешь дело с большим объемом данных, надо работать с данными как с потоком: обрабатывать по мере поступления, не копить. XML это ведь просто текст, размеченный определенным нехитрым образом! Не надо вам никаких библиотек для него. Просто выводите текст: сперва некий заголовок, а потом в цикле: одна запись => вывод одной строки XML, по завершении цикла закрывающие теги XML. Так вы получите время чуть-чуть больше, чем время добычи данных из mysql.
После выполнения запроса все полученные значения записываются в переменную с помощью функции mysql_fetch_array, а уже потом в цикле из переменной достаю данные и вставляю в нужные теги xml. artoodetoo, можете поподробней объяснить про "Просто выводите текст: сперва некий заголовок, а потом в цикле: одна запись => вывод одной строки XML, по завершении цикла закрывающие теги XML."
Сперва вы расскажите сколько примерно строк выдает ваш запрос, что за "переменная", что значит "через DOM" и что значит "вставляю в нужные теги". Есть варианты! Лучше всего скопируйте сюда рабочий цикл. А то может я домысливаю чего неправильно.
Код (Text): ... $vidpolis = mysql_query("SELECT *FROM Table); // создаю объект DOM $dom = new domDocument("1.0", "windows-1251"); $dom->preserveWhiteSpace = false; $dom->formatOutput = true; ... $i=0; while ($vdp = mysql_fetch_array($vidpolis)){ $i++; ... // далее заполняю теги в xml данными $id_pac = $pacient->appendChild($dom->createElement("ID_PAC")); $id_pac->appendChild($dom->createTextNode($i)); $vpolis = $pacient->appendChild($dom->createElement("VPOLIS")); $vpolis->appendChild($dom->createTextNode($vdp[policyType_id])); $npolis = $pacient->appendChild($dom->createElement("NPOLIS")); $npolis->appendChild($dom->createTextNode($vdp[number])); $smo = $pacient->appendChild($dom->createElement("SMO")); $smo->appendChild($dom->createTextNode($vdp[infisCode])); ... // и всё сохраняем в файл $dom->save("D:/HM460061T.xml"); }
Вы что, реально сохраняете при каждой итерации цикла? Тогда неудивительно, что так долго. Вынесите save() ниже } Добавлено спустя 6 минут 57 секунд: Это если ничего не менять, а только исправить косяк. А на самом деле я советовал вам заглянуть в готовый XML и сделать примерно так: Код (PHP): // шапка XML echo "<?xml version=\"1.0\" encoding=\"windows-1251\"?> <polises> "; // пошли элементы while ($vdp = mysql_fetch_array($vidpolis)) { echo " <VPOLIS>{$vdp[policyType_id]}</VPOLIS> <NPOLIS>{$vdp[number]}</NPOLIS> "; } // элементы кончились, закрываем набор echo " </polises> "; Данные я тут привел от балды, надеюсь принцип понятен? Не копим, а сразу выводим. Память не тратится, накладные расходы на вывод минимальные. Добавлено спустя 7 минут 36 секунд: Между делом замечания по mysql: 1. расширение mysql устарело и про него надо начинать забывать. Пользуйтесь аналогичными функциями mysqli 2. Мы вродебы говорим о БОЛЬШОМ количестве данных. mysql_query работает так: если операция успешна, результат ПОЛНОСТЬЮ выкачивается и помещается в буфер клиента и потом по мере fetch выдается в приложение. вместо этого можно воспользоваться НЕбуферизирующей версией mysql_unbuffered_query. она медленнее, но память клиента mysql расходуется экономнее. это может быть критически важно.
Спасиб, вам, большое. Все получилось так так надо, всё формируется и быстро выгружается. По поводу сохранения каждый раз. Да, затупил не много. Чё-то показалось, что он добавляет каждую итерацию цикла в конец файла. Вот и сделал сохранение в конце цикла.