помогите создать страницу с длительным по времени запросом к БД

Тема в разделе "Как сделать...", создана пользователем Killer67, 17 окт 2015.

  1. Killer67

    Killer67 Постоялец

    Регистр.:
    25 мар 2012
    Сообщения:
    55
    Симпатии:
    4
    Предисловие в кратце:
    У меня есть относительно крупная БД и запрос который формирует статистику из нее.
    Я выполняю его через WorkBench на сервере с БД, запрос выполняется по времени примерно 20 - 30 минут и результат выводится в файл для последующего анализа.

    Вопрос:
    Как составить страницу автоматизирующую данное действие?

    Функции формы примерно такие:
    - Если isset($_POST[QueryFormName]); то обработка формы.
    -- В этот момент выводится прогресс бар на время примерно 10 минут
    -- Обновляем страницу, если запрос не выполнился, то еще раз прогресс бар на 10 минут
    -- Если запрос выполнился то отправляем файл на скачку в браузер и выводим его же содержимое на страницу.

    - Если запроса из формы нет то выводим форму с name = "QueryFormName"

    Из всего этого я знаю только самое примитивное:
    - выполнение условий (обработка если запрос есть или вывод формы если запроса нет)
    - Упаковка файла в архив и передача его на скачивание
    - Вывод файла в браузер построчно (без глюков когда выводится весь текст в одну строку по возможности)

    Остались только задачи:
    - Как вывести прогресс бар (код максимально проще, минимум строк кода)
    - Как узнать что запрос еще в процессе выполнения?

    Или может быть изменить эти 2 задачи в одну:
    Прогресс бар пока выполняется запрос, но на сколько я знаю это не возможно т.к. сам элемент выполняется на стороне клиента и он понятия не имеет что происходит с самим запросом который выполняет php с mysql еще до того как передать данные в MySQL.

    Ну и на последок:
    Если кто сталкивался с подобным, какие подводные камни (возможно нужно применить до всего этого ini_set(timeout) до того как все это начнет работать )?
     
  2. primehostnet

    primehostnet Постоялец

    Регистр.:
    28 июн 2015
    Сообщения:
    98
    Симпатии:
    17
    я думаю, что если вы из всего этого знаете только самое элементарное, то стоит обратиться к тому кто знает больше чем вы.
    Так на вскидку вижу это так
    1. допустим вы выбираете из базы несколько миллионов, миллиардов записей, оптимально делать это по этапно
    2. сначала считаем сколько всего записей нужно выбрать,
    3. затем делим это на этапы, скажем на 10 или больше
    4. теперь при помощи аякса запускаем запросы один за другим, по окончанию предыдущего меняем прогресбар
    по окончания последнего запроса выводим результат.

    откровенно говоря я сомневаюсь что у вас на столько большие объемы которые требуют 20-30 минут. Скорее всего кривые запросы или кривая бд.
    Пишите в лс, интересно было бы посмотреть ближе
     
    Killer67 нравится это.
  3. javx

    javx

    Регистр.:
    28 авг 2015
    Сообщения:
    521
    Симпатии:
    239
    "- Как узнать что запрос еще в процессе выполнения?" как вариант, в конце запроса записывать в какую то табличку текущее время. Потом скрипт достукивается к этой табличке и смотрит на время, если оно старое (с последнего выполнения запроса) то возвращает ответ что еще не выполнился запрос. И если недавнешнее время то говорит - запрос завершился.
     
  4. primehostnet

    primehostnet Постоялец

    Регистр.:
    28 июн 2015
    Сообщения:
    98
    Симпатии:
    17
    по поводу этого, самый простой вариант, on success (alert('готовов n%');) и запускаем следующий этап.
     
  5. kto-to

    kto-to Создатель

    Регистр.:
    19 май 2012
    Сообщения:
    14
    Симпатии:
    2
    "Какая-то" табличка уже какбэ встроенная в MySQL и никто не мешает сделать запрос
    SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND !='Sleep';

    либо
    show processlist;
     
    Последнее редактирование модератором: 28 окт 2015
    Killer67 нравится это.
  6. Killer67

    Killer67 Постоялец

    Регистр.:
    25 мар 2012
    Сообщения:
    55
    Симпатии:
    4
    Возьму на вооружение..
    Пока решилось совсем по другому...
    т.к. следующая страница не загрузится пока в ПХП не вернеться результат запроса из MySQL, мы можем открыть gif-ку типа идет процесс, и когда новая страница с результатом уже будет возвращаться из ПХП, то страница практически мнгновенно загрузится в браузер, что соотвественно и закроет гифку...

    Таким образом мы показали пользователю:
    1. Процесс выполняется
    2. Процесс завершен

    Соотвественно я так понял прогресс-бар сделать не получится, т.к. "страница не загрузится пока в ПХП не вернеться результат запроса из MySQL"...
    Или есть способы обхода?

    Засек штатными средствами пхп время выполнения запроса, 41 - минута, единственный вариант который я смог придумать это запустить аякс прогресс бар по таймеру и т.к. я уже примерно знаю сколько запрос будет выполняться, запустить заполнение прогресс бара по таймеру, а в таймере поставить не 41 минуту а 45, ну всяко будет как то понятно, что вот вот, скоро закончится....

    Да к стати, может есть у кого нить в запасе короткий код для заполнения прогресс бара по таймеру?
     
  7. javx

    javx

    Регистр.:
    28 авг 2015
    Сообщения:
    521
    Симпатии:
    239
    как вариант, для точного вывода времени: при считывании статистики - параллельно менять значение в какой то ячейке. т.е. аякс смотрит на число в этой ячейке "50" а всего данных "100" таким образом он передает что полоску состояния нужно заполнять на 50%. Но это если статистика считывается порциями отдельных запросов, а не одним сплошным.
     
  8. primehostnet

    primehostnet Постоялец

    Регистр.:
    28 июн 2015
    Сообщения:
    98
    Симпатии:
    17
    прогресс бар не заполняют по таймеру, а вдруг в этот раз сервер еще чем то загружен и то что раньше работало за 1 минуту, теперь работает 2? или наоборот? прогресс бар заполняют по выполнению этапов процесса... на то он и прогресс бар.
     
  9. kto-to

    kto-to Создатель

    Регистр.:
    19 май 2012
    Сообщения:
    14
    Симпатии:
    2
    Есть вероятность, что запрос у вас кривоват, либо подход не правильный.. покажите пример с данными и сам запрос. Возможно мы коллективным разумом придумаем как его переделать, чтобы запрос в процессе выполнения обновлял какой-то флаг, к которому мы прицепимся через ajax и сделаем красивый прогресс бар.

    Даже если у вас в запросе агрегирующие функции - всеравно там должен работать LIMIT.