| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > PHP: Базы Данных > Обработка базы в несколько потоков |
| Автор: Ibragim 17.5.2007, 22:51 |
| Вечер добрый. Есть следующая ситуация. Данные хранятся в таблице MySQL, положим, с тремя полями id, name, value В таблице name уже присвоены, а рассчтать и заполнить значения value и стоит задача. Имея один "обработчик", мы делаем так 1. Выбираем очередную необработанню запись: SELECT id, name FROM `my_table` WHERE value="" LIMIT 1 2. Исходя из name рассчитываем значение value 3. Сохраняем значение value: UPDATE `my_table` SET value="<рассчитанное value>" WHERE id="<соотв. id>" Но задача стоит сделать много обработчиков, то есть много копий скрипта, обновляющих эти значение value параллельно. Счас реализовано вот так: 1. UPDATE `my_table` SET value="<уникальное сгенерированное значение>" WHERE value="" LIMIT 1 2. SELECT id, name FROM `my_table` WHERE value="<это сгенерированное значение>" 3. Рассчет значения value 4. Сохранение UPDATE `my_table` SET value="<рассчитанное value>" WHERE id="<соотв. id>" Есть ли более оптимальный способ "сказать" mysql что данная запись уже обрабатывается другой копией скрипта, и надо выбрать следующую? Как обычно поступают в таких случаях? |
| Автор: -=Ustas=- 18.5.2007, 14:20 |
| Делай промежуточную табличку очередей, в которую ты сначала считаваешь записи, а затем уже запускаешь сколько угодно скриптов, которые из этой таблички выбирают верхние записи, и следовательно сразу же свою запись грохают, хотя может при выборе верхней записи каждым экземпляром скрипта нужно будет еще лочить таблицу. |
| Автор: WolfON 18.5.2007, 17:17 |
| А расчет значения нельзя осуществить в рамках синтаксиса SQL-запросов (даже если с промежуточными таблицами) ? Тут все все-таки упирается в скорость выполнения запросов сервером, а не в том, как часто их может посылать скрипт (если расчеты не сложные, выигрыш от многопоточности будет мизерным, да и не обязательно, что будет) Еще можно почитать вот это: http://dev.mysql.com/doc/refman/5.0/en/lock-tables.html |
| Автор: Ibragim 18.5.2007, 21:50 |
| 2-=Ustas=-: спасибо за совет, только практически я ео реализовать не представляю как. Таблица `my_table` достаточно велика, делать ее КОПИЮ чтобы из нее делетить не представляется возможным. А если делать маленькую промежуточную, то получается еще один скрипт, который "наполняет" по мере обсчитывания эту промежуточную следующими значениями из большой. Наверно будет быстрее (меньше запросов к большой таблице), но уж очень "витиевато" получается, буду думать. 2WolfON: Я однозначно уверен что нужно много потоков ввиду специфики задачи. Рассчет - понятие условное, включает в себя закачивание из интернета, ожидание от медленных серверов и так далее. PS Да, а можно как-то залочить именно записть и сказать MySQL "SELECT name FROM `mytable` WHERE value="" AND <ЗАПИСЬ_НЕ_ЗАЛОЧЕНА> LIMIT 1" ? |
| Автор: teroni 24.5.2007, 23:13 |
| Я обычно в таких случаях делаю текстовый файл, в котором изначально записан 0. При запуске каждая копия обработчика считывает это значение, и записывает в файл на единицу большее. Таким образом, каждый работающий скрипт-обрабочик имеет свой уникальный ID и в соответствии с этим уже делает свою работу. |
| Автор: Ibragim 15.6.2007, 20:30 |
| Если еще кому-то будет интересно напишу как в конце-концов реализовал. Сделал еще одну таблицу с одним полем и одной записью Каждый обработчик - лочит эту вспомог. таблицу - читает из вспомогательной таблицы значение ее единственной записи, скажем my_var - считывает из основной следующее значение так: WHERE primary_key > my_var ORDER BY primary_key - записывает во вспомог. таблицу PRIMARY key текущего значения - разлочивает вспомог. таблицу. То есть фактически в вспомогательной таблице находится переменная, значение которой равно "ID последней ВЗЯТОЙ НА ОБРАБОТКУ записи основной таблицы". PS ORDER BY primary_key не тормозит обработку ни в коей мере. Вот, может кому пригодится. |