![]() |
Модераторы: skyboy, MoLeX, Aliance, ksnk |
![]() ![]() ![]() |
|
Ibragim |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 177 Регистрация: 28.9.2004 Где: Киев Репутация: нет Всего: нет |
Вечер добрый.
Есть следующая ситуация. Данные хранятся в таблице 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=- |
|
|||
![]() Ustix IT Group ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2222 Регистрация: 21.1.2005 Где: Краснодар Репутация: 17 Всего: 69 |
Делай промежуточную табличку очередей, в которую ты сначала считаваешь записи, а затем уже запускаешь сколько угодно скриптов, которые из этой таблички выбирают верхние записи, и следовательно сразу же свою запись грохают, хотя может при выборе верхней записи каждым экземпляром скрипта нужно будет еще лочить таблицу.
-------------------- В искаженном мире все догмы одинаково произвольны, включая догму о произвольности догм. ----- |
|||
|
||||
WolfON |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 604 Регистрация: 19.7.2004 Репутация: нет Всего: 8 |
А расчет значения нельзя осуществить в рамках синтаксиса SQL-запросов (даже если с промежуточными таблицами) ?
Тут все все-таки упирается в скорость выполнения запросов сервером, а не в том, как часто их может посылать скрипт (если расчеты не сложные, выигрыш от многопоточности будет мизерным, да и не обязательно, что будет) Еще можно почитать вот это: http://dev.mysql.com/doc/refman/5.0/en/lock-tables.html |
|||
|
||||
Ibragim |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 177 Регистрация: 28.9.2004 Где: Киев Репутация: нет Всего: нет |
2-=Ustas=-: спасибо за совет, только практически я ео реализовать не представляю как. Таблица `my_table` достаточно велика, делать ее КОПИЮ чтобы из нее делетить не представляется возможным. А если делать маленькую промежуточную, то получается еще один скрипт, который "наполняет" по мере обсчитывания эту промежуточную следующими значениями из большой. Наверно будет быстрее (меньше запросов к большой таблице), но уж очень "витиевато" получается, буду думать.
2WolfON: Я однозначно уверен что нужно много потоков ввиду специфики задачи. Рассчет - понятие условное, включает в себя закачивание из интернета, ожидание от медленных серверов и так далее. PS Да, а можно как-то залочить именно записть и сказать MySQL "SELECT name FROM `mytable` WHERE value="" AND <ЗАПИСЬ_НЕ_ЗАЛОЧЕНА> LIMIT 1" ? Это сообщение отредактировал(а) Ibragim - 18.5.2007, 21:57 |
|||
|
||||
sTa1kEr |
|
||||
9/10 программиста ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1553 Регистрация: 21.2.2007 Репутация: 9 Всего: 146 |
Ibragim,
В таком случае можно создать временную таблицу в памяти и записывать в нее id обрабатываемых в данный момент строк. А при выборке новых строк для обработки делать LEFT JOIN на нее с условием на неравенство id-шников. Если же value заполняется только один раз для каждой строки, то еще оптимальней записывать только один id, а дальше делать выборку большему значению.
Залочить-то одну строку можно (для таблиц типа InnoDB), но вот просто пропустить залоченную строку при выборке не получится, остальные запросы будут ждать когда ее разлочат. Это сообщение отредактировал(а) sTa1kEr - 24.5.2007, 19:48 |
||||
|
|||||
teroni |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 381 Регистрация: 15.5.2007 Где: Днепропетровск Репутация: 3 Всего: 22 |
Я обычно в таких случаях делаю текстовый файл, в котором изначально записан 0. При запуске каждая копия обработчика считывает это значение, и записывает в файл на единицу большее. Таким образом, каждый работающий скрипт-обрабочик имеет свой уникальный ID и в соответствии с этим уже делает свою работу.
|
|||
|
||||
Ibragim |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 177 Регистрация: 28.9.2004 Где: Киев Репутация: нет Всего: нет |
Если еще кому-то будет интересно напишу как в конце-концов реализовал.
Сделал еще одну таблицу с одним полем и одной записью Каждый обработчик - лочит эту вспомог. таблицу - читает из вспомогательной таблицы значение ее единственной записи, скажем my_var - считывает из основной следующее значение так: WHERE primary_key > my_var ORDER BY primary_key - записывает во вспомог. таблицу PRIMARY key текущего значения - разлочивает вспомог. таблицу. То есть фактически в вспомогательной таблице находится переменная, значение которой равно "ID последней ВЗЯТОЙ НА ОБРАБОТКУ записи основной таблицы". PS ORDER BY primary_key не тормозит обработку ни в коей мере. Вот, может кому пригодится. |
|||
|
||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | PHP: Базы Данных | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |