Артем Л.
11416 повідомлень
#15 років тому
Суть такая.

Есть таблица с записями. Берем из нее данные в многомерный массив.

Имеем:
1. Многомерный массив с данными (текст порядка 100 записей около 5К символов+- каждая)
2. Порядка 100 таблиц в БД

Каждой записи в массиве соответствует какой-то параметр (допустим тематика), по которому определяется в какую именно БД нужно записать данные из массива.

Нужно по крону запускать скрипт, который будет сортировать данный массив и раскидывать данные по таблицам.

Суть такая...
1. Делаем инсерты в разные таблицы из разных ячеек массива в соответствии с тематикой.
2. Для каждого инсерта если все прошло успешно делаем 1 инсерт в отдельную табличку, что все ок.
3. Для каждого инсерта если все прошло успешно, подчищаем из первоначальной таблицы эту запись которую перенесли в итоге в другую табличку.

В итоге получается порядка 300 запросов и большой объем данных. Боюсь что хостинг не справится и все будет падать.

Подскажите как это дело можно оптимизировать? Есть какие-то идеи?
Может тупо разбить по частям и запускать крон несколько раз?
Спасибо.
Евгений О.
2989 повідомлень
#15 років тому
Цитата ("Hungry_Hunter"):
В итоге получается порядка 300 запросов и большой объем данных.

300 * 1.5М - это в общем-то немного. Я тут на одном сайте дошел почти до 1500 запросов на создание 1 страницы! И останавливаться на достигнутом не собираюсь .
Если это разовая работа, то лучше всего именно "Может тупо разбить по частям и запускать крон несколько раз".
Артем Л.
11416 повідомлень
#15 років тому
Цитата ("elosoft"):
Если это разовая работа, то лучше всего именно "Может тупо разбить по частям и запускать крон несколько раз".

Не, это будет каждый день в течении долгих лет Хотя можно разбить конечно, хотя там и без этого заданий по крону огого будет А если еще учесть что на хостинге не особо удобный интерфейс работы с кроном (вводятся команды в линуксовском формате), то вообще ужас

Цитата ("elosoft"):
Я тут на одном сайте дошел почти до 1500 запросов на создание 1 страницы!

Жесть конечно
Никита К.
1594 повідомлення
#15 років тому
Ну так в линуксовском формате и задаем выполнение php скрипта в определенной папке через интерпретатор пхп...
Вопрос в том, что зачастую на хостингах это можно делать только из админ-панели...
Евгений О.
2989 повідомлень
#15 років тому
Цитата ("Hungry_Hunter"):
Жесть конечно

Не, не жесть. Требование заказчика. Там куча статистики собирается, а хранить ее в промежуточной таблице заказчик не соглашается.
Но реально, конечно так не работает. Это без кэширования. При включенном кэше где-то 5-8 запросов на страницу.
Евгений О.
2989 повідомлень
#15 років тому
А по Вашему скрипту я бы предложил разделить скрип на части по задачам. Один выполняет запись, другой ставит отметки, третий чистит таблицы.
Артем Л.
11416 повідомлень
#15 років тому
Цитата ("Anexroid"):
Ну так в линуксовском формате и задаем выполнение php скрипта в определенной папке через интерпретатор пхп...
Вопрос в том, что зачастую на хостингах это можно делать только из админ-панели...

Я просто раньше особо не сталкивался с кронтабом, разве что на парах в инсте
Видел где-то интерфейс, где просто выбираются из менюшек периодичность и указывается путь к запускаемому php файлу, вот было удобно А так как-то не особо хочется копаться в таком кронтабе

Цитата ("elosoft"):
А по Вашему скрипту я бы предложил разделить скрип на части по задачам. Один выполняет запись, другой ставит отметки, третий чистит таблицы.

Ну да, можно и так попробовать
Николай М.
1895 повідомлень
#15 років тому
Цитата ("Hungry_Hunter"):
Суть такая...
1. Делаем инсерты в разные таблицы из разных ячеек массива в соответствии с тематикой.
2. Для каждого инсерта если все прошло успешно делаем 1 инсерт в отдельную табличку, что все ок.
3. Для каждого инсерта если все прошло успешно, подчищаем из первоначальной таблицы эту запись которую перенесли в итоге в другую табличку.


Это нужно сделать с помощью 1 транзакции, с полным откатом в случаи неудачи, но тогда все будет лежать пока не отработает.
Значит, нужно сделать вюху в нашим OLAP-кубом, мускул не очень хорошо это делает, но всетаки делает)
на вюху можно навешать тригера, с них роскидать данные сразуже, я бы наверное попытался так.
Артем Л.
11416 повідомлень
#15 років тому
MMM_Corp жестоко
У меня версия не дотягивает до использования тригеров

Пожалуй просто придется сделать разбить этот процесс, и запускать крон несколько раз, так проще будет я думаю...
Сергей Шпак
596 повідомлень
#15 років тому
Если уж извращаться, делал-бы как-то так :
SQlite3 (с пхп5 идет в комплекте по дефолту SQlite2 ) - меньше грузим сервер, используем транзакции и тригеры.
Формат работы почти такой же как и с Мускулом.

ps.
Николай Т.
205 повідомлень
#15 років тому
Хм, перекинуть данные из одной таблицы в другую поможет INSERT SELECT, если происходит ошибка в транзакции то разбираемся с ней... (это позволяет забить на второй пункт), очистку делаем как нравится
разные скрипты имхо не нужны, достаточно одного, тики к сожалению из php убираются, поэтому в некоторых участках кода можно повесить функцию проверки загруженности проца/оперативы и делать sleep на пару секунд...
скрипт лучше запускать не в 12 ночи, а в 2-3, тогда - когда нагрузка на сервер минимальная.
Роман Ч.
762 повідомлення
#15 років тому
Цитата ("Hungry_Hunter"):
Суть такая.
В итоге получается порядка 300 запросов и большой объем данных. Боюсь что хостинг не справится и все будет падать.

Подскажите как это дело можно оптимизировать? Есть какие-то идеи?


идея: не мучить хостера и юзверей-соседей по хостинг-серверу, а юзать vps

и прислушаться к совету e1it3, если нет возможности юзать SQlite3
Евгений О.
263 повідомлення
#15 років тому
Цитата ("Hungry_Hunter"):
В итоге получается порядка 300 запросов и большой объем данных. Боюсь что хостинг не справится и все будет падать.


300 запросов и 100 таблиц по 100 записей - это 10000 записей по 5K или всего 50Мбайт данных - и это по Вашему много??? Тут сейчас один сервер MySQL стоит - 2047 открытых таблиц, 101 запрос в сек., гигабайт трафика в час и в результате загрузка процессора 0.08.

Если Вы опасаетесь за нервную систему Вашего хостинг-провайдера, то загрузите все 100 таблиц в память, модифицируйте их там и выгрузите обратно. Хотя, если есть время, то можно, конечно, поосваивать новые технологии, views там применить, хранимые процедуры как-нибудь приспособить, триггера к чему-нибудь приставить - это будет поучительно и занимательно. Только Вашу программу это не сделает более эффективной, поскольку "там внутри" всего один диск и всего один набор головок чтения/записи.
Артем Л.
11416 повідомлень
#15 років тому
Всем спасибо за интересные советы, новые технологии и т.д. но мы пока со стареньким софтом
Дабы не травмировать хостинг-провайдера я просто буду каждый час теребить кроном скрипт и пусть оно работает Так даже интереснее получится
Хотя этот провайдер выдерживал порядка 80К уников в сутки и не жаловался на меня, так что думаю осилит

Цитата ("e1it3"):
Хм, перекинуть данные из одной таблицы в другую поможет INSERT SELECT, если происходит ошибка в транзакции то разбираемся с ней... (это позволяет забить на второй пункт)

Второй пункт нужен обязательно, там помимо галочки что все прошло еще некоторые данные пишутся...

Illarion_SA ну для сервера да, а вот хостинг думаю будет ругаться
Евгений О.
2989 повідомлень
#15 років тому
С INSERT SELECT обычно вот на этом налетают
Оффтопик
Целевая таблица команды INSERT не должна появляться в утверждении FROM части SELECT данного запроса, поскольку в ANSI SQL запрещено производить выборку из той же таблицы, в которую производится вставка. (Проблема заключается в том, что операция SELECT, возможно, найдет записи, которые были внесены ранее в течение того же самого прогона команды. При использовании команд, внутри которых содержатся многоступенчатые выборки, можно легко попасть в очень запутанную ситуацию!)
Вадим Т.
3240 повідомлень
#15 років тому
Любые способы это сделать без использования транзакций - сложны и ненадежны. Если БД одна (или несколько БД на одном инстансе сервера БД), тут даже и думать нечего, типовая задача.
Если таблицы не на одной БД, а на нескольких, которые находятся на разных серверах (или на разных инстансах), тогда нужно использовать так называемые "длинные транзакции", но это уже намного сложнее в реализации.

Если у Вас MySQL, пожалуйста проверьте, поддерживается ли InnoDB. Если нет - меняйте хостинг. MySQL/MyISAM транзакции не поддерживает.
Артем Л.
11416 повідомлень
#15 років тому
У меня MySQL, менять ради этой задачи хостинг смысла нет Да и реализовал я уже, всем спасибо