Цикл на php и Ajax

Как сделать циклический запуск функции php из аякса?

#1 15 марта 2016 в 12:23
Есть надобность обработки больших таблиц базы данных (более миллиона строк).
Все сделано довольно просто: селект из базы данных, обработка скриптом пхп, запись обратно в базу.
Вся беда в том, что на полумиллионе заканчивается память сервера и скрипт вываливается в ошибку.
Пробовал сделать цикл на php, обрабатывать пачками по 10000 строк и очищать память между итерациями — не тут то было! Никакие unset не помогают, пхп упорно держит всё в оперативке до окончания цикла.

Отсюда возникла идея, стартовать скрипт пхп из цикла на аяксе, можно даже с промежуточным отображением результатов.
Вся беда в том, что мои познания в яваскрипте не просто никакие, а даже слегка минусовые. smile

Кто может подсказать, возможно ли сделать такое?
То есть запуск яваскрипта по клику, из яваскрипта отправляется значение начала выборки для скрипта пхп, тот выбирает строки из базы с ограничением LIMIT $n, 10000, обрабатывает эти строки, отправляет значение $n яваскрипту и прекращает свою работу, тот увеличивает значение на 10000, отображает промежуточный результат (можно и не отображать) и снова запускает скрипт пхп с новым значением $n
#2 15 марта 2016 в 12:57
скрипт то написать возможно, вот только не уверен потянет ли это браузер, 10000 строк, это же какой ответ будет возвращать сервер, это же сколько строк ему надо будет обработать

а вообще скрипт вижу примерно так

var count = 10000;
var page = 1;

function getRows(){

$.ajax({
type: "POST",
url: "getrows.php",
dataType: "json",
data: "count="+count+"&page="+page,
success: function(data){
if (!data) return false;
else{
//что-то делаем с данными
page++;
getRows();
}
}
});

}

getRows();

на сервере берем переменные и исходя из них делаем выборку. если есть записи, возвращаем строку в формате json, если нет, то возвращаем false.

скажу честно, скрипт не тестировал smile
#3 15 марта 2016 в 12:59
Вот тут очень хорошо расписано как работать с аякс (+ примеры).
Но не понимаю, как это поможет в вашей проблеме? Я к тому что подход изначально не правильный, и вы пытаетесь решить проблему "костыльным методом".
#4 15 марта 2016 в 13:05

скрипт то написать возможно, вот только не уверен потянет ли это браузер, 10000 строк, это же какой ответ будет возвращать сервер,

AbdullaAlt
Скрпит на аяксе должен возвращать скрипту пхп только одну величину — значение $n
Дальше с этим значением заново запускается функция php на сервере, обрабатывает строки, отправляет значение $n скрипту аякс и завершает работу.
Скрипт на аяксе увеличивает значение на 10000 (или на 1, тогда в пхп скрипте просто изменить лимит на ( LIMIT $n*10000, 10000) и запускает скрипт пхп с новым значением $n.

Вот тут очень хорошо расписано как работать с аякс

Val
Вот только не очень хорошо расписано, что означают все эти [settings] и не очень понятно, как запустить не файл script.php, а определенную функцию в этом файле.

Но не понимаю, как это поможет в вашей проблеме?

Val
Прекращение работы скрипта пхп очистит оперативную память сервера. Когда он будет запущен с новым значением начала выборки из базы — все переменные из предыдущего цикла будут удалены.


Я к тому что подход изначально не правильный, и вы пытаетесь решить проблему "костыльным методом".

Val
Что можете предложить?
#5 15 марта 2016 в 13:10

Вся беда в том, что на полумиллионе заканчивается память сервера и скрипт вываливается в ошибку.
Пробовал сделать цикл на php, обрабатывать пачками по 10000 строк и очищать память между итерациями -

В зоне одной сессии?
#6 15 марта 2016 в 13:14
Когда мне нужно обработать большое количество строк я складываются все I'd существующих записей в файл. Вырезаю ид из файла. Select из базы, манипуляции, update и т д close connect
В страницу со скриптом ставлю мета рефреш 1 секунду. И открываю в 1-10 вкладках.
Мне как то нужно было обновить содержимое 30000 строк в БД, я просто не смог составить запрос Notepad лагал и приходилось все делать заново. Таким способом обновил за пару часов. Может как то так…
#7 15 марта 2016 в 13:15

В зоне одной сессии ?

Геннадий Иванович
Да.

Если вручную прописать LIMIT 0, 10000, отработать скрипт, потом вручную изменить на LIMIT 10000, 10000, LIMIT 20000, 10000 — всё работает как надо.
Я просто хочу автоматизировать процесс.

Мне как то нужно было обновить содержимое 30000 строк в БД, я просто не смог составить запрос Notepad лагал и приходилось все делать заново. Таким способом за пару часов. Может как то так...

Нил™
У меня чуть больше миллиона строк. В два приема по 600 тысяч на опенсервере с 1.5 гигами оперативки операция длится 40 минут.
#8 15 марта 2016 в 13:27

Геннадий Иванович:
В зоне одной сессии ?
Да.

HiAndy
Так продолжайте свои мысли: — А если использовать новую сессию для каждого лимита памяти? Или для каждой пачки по 10000 запросовиспользовать свою сессию?
#9 15 марта 2016 в 13:29

для каждой пачки по 10000 запросов использовать свою сессию?

Геннадий Иванович
Да!
Как это сделать?
#10 15 марта 2016 в 13:39

Прекращение работы скрипта пхп очистит оперативную память сервера. Когда он будет запущен с новым значением начала выборки из базы — все переменные из предыдущего цикла будут удалены.

HiAndy
Что вы хотели сделать я понял))

Я к тому что подход изначально не правильный

Val

Прислушайтесь к Геннадий Иванович!
#11 15 марта 2016 в 13:43

Прислушайтесь к Геннадий Иванович!

Val
Геннадий Иванович говорит намеками.
Можно ли расписать поподробнее, как разбить обработку большой таблицы на части, чтобы разгрузить память?
#12 15 марта 2016 в 13:43

Как это сделать?

HiAndy
Теоретически?
Нужно между сессиями сохранить временные данные начало ID-0-строк: завершено ID=10000
Создать табличку и сохранять в ней результат.

Пробовал сделать цикл на php, обрабатывать пачками по 10000 строк и очищать память между итерациями

HiAndy
Значит сохранить результат обработанных строк не проблема !
Инициализировать новую сессию, считать где закончили обработку, продолжить, и дт.
Просто Ваша подача вопроса,

Есть надобность обработки больших таблиц базы данных (более миллиона строк).

не раскрывает методов к возможному решению. Все это так в принципе.
Поэтому и ожидаемые Вами ответы, базируются на предположениях.
#13 15 марта 2016 в 13:48

Геннадий Иванович говорит намеками.

HiAndy
Ну так и мы не знаем вашего кода и целей.

HiAndy, курим сначала маны
#14 15 марта 2016 в 13:53

Нужно между сессиями сохранить временные данные начало ID-0-строк: завершено ID=10000

Геннадий Иванович
Не нужно. Нужно просто сохранить значение переменной $n, остановить скрипт и после начать его заново увеличив значение переменной.
Я надеялся, что запуск одного скрипта из цикла в другом скрипте решит вопрос, но не тут то было!
Пока цикл полностью не отработает — память не очищается.


Просто Ваша подача вопроса ,
Есть надобность обработки больших таблиц базы данных (более миллиона строк).
не раскрывает методов к возможному решению. Все это так в принципе.
Поэтому и ожидаемые Вами ответы, базируются на предположениях.

Геннадий Иванович

Вас понял. Сейчас немножко облагорожу внешний вид и выложу почти готовое изделие.
Может тогда будет понятнее, что я имел в виду…
#15 15 марта 2016 в 14:14

Может тогда будет понятнее, что я имел в виду...

HiAndy
1- Если это процесс систематический то: лучше cоздать задание для cron ( обработка и счетчик обработанных строк таблицы) и выполнять по заданию определенный промежуток времени — определенное количество строк.
2- Если это единовременный но периодический процесс разработчика, то решений много.
Обычно такая обработка больших данных, это вынужденная мера к обработке "спарсенных" данных (результатов выдачи с доноров). и как следствие пост обработка и определенная "уникализация" контента.
Вы не можете отвечать в этой теме.
Войдите или зарегистрируйтесь, чтобы писать на форуме.
Используя этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.