Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Обработка базы в несколько потоков, даже не знаю как это еще сформулировать 
V
    Опции темы
Ibragim
Дата 17.5.2007, 22:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 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 что данная запись уже обрабатывается другой копией скрипта, и надо выбрать следующую? Как обычно поступают в таких случаях?
PM MAIL   Вверх
-=Ustas=-
Дата 18.5.2007, 14:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ustix IT Group
****


Профиль
Группа: Участник Клуба
Сообщений: 2222
Регистрация: 21.1.2005
Где: Краснодар

Репутация: 17
Всего: 69



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


--------------------
В искаженном мире все догмы одинаково произвольны, включая догму о произвольности догм.
-----
PM WWW ICQ Skype   Вверх
WolfON
Дата 18.5.2007, 17:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 604
Регистрация: 19.7.2004

Репутация: нет
Всего: 8



А расчет значения нельзя осуществить в рамках синтаксиса SQL-запросов (даже если с промежуточными таблицами) ?

Тут все все-таки упирается в скорость выполнения запросов сервером, а не в том, как часто их может посылать скрипт (если расчеты не сложные, выигрыш от многопоточности будет мизерным, да и не обязательно, что будет)


Еще можно почитать вот это:
http://dev.mysql.com/doc/refman/5.0/en/lock-tables.html 
PM MAIL ICQ   Вверх
Ibragim
Дата 18.5.2007, 21:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 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
PM MAIL   Вверх
sTa1kEr
Дата 24.5.2007, 19:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 9
Всего: 146



Ibragim
Цитата(Ibragim @  18.5.2007,  21:50 Найти цитируемый пост)
Таблица `my_table` достаточно велика, делать ее КОПИЮ чтобы из нее делетить не представляется возможным.

В таком случае можно создать временную таблицу в памяти и записывать в нее id обрабатываемых в данный момент строк. А при выборке новых строк для обработки делать LEFT JOIN на нее с условием на неравенство id-шников.

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

Цитата(Ibragim @  18.5.2007,  21:50 Найти цитируемый пост)
PS Да, а можно как-то залочить именно записть и сказать MySQL "SELECT name FROM `mytable` WHERE value="" AND <ЗАПИСЬ_НЕ_ЗАЛОЧЕНА> LIMIT 1" ?

Залочить-то одну строку можно (для таблиц типа InnoDB), но вот просто пропустить залоченную строку при выборке не получится, остальные запросы будут ждать когда ее разлочат.

Это сообщение отредактировал(а) sTa1kEr - 24.5.2007, 19:48
PM MAIL   Вверх
teroni
Дата 24.5.2007, 23:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 381
Регистрация: 15.5.2007
Где: Днепропетровск

Репутация: 3
Всего: 22



Я обычно в таких случаях делаю текстовый файл, в котором изначально записан 0. При запуске каждая копия обработчика считывает это значение, и записывает в файл на единицу большее. Таким образом, каждый работающий скрипт-обрабочик имеет свой уникальный ID и в соответствии с этим уже делает свою работу.
PM MAIL   Вверх
Ibragim
Дата 15.6.2007, 20:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 28.9.2004
Где: Киев

Репутация: нет
Всего: нет



Если еще кому-то будет интересно напишу как в конце-концов реализовал.
Сделал еще одну таблицу с одним полем и одной записью

Каждый обработчик
- лочит эту вспомог. таблицу
- читает из вспомогательной таблицы значение ее единственной записи, скажем my_var
- считывает из основной следующее значение так: WHERE primary_key > my_var ORDER BY primary_key
- записывает во вспомог. таблицу PRIMARY key текущего значения
- разлочивает вспомог. таблицу.

То есть фактически в вспомогательной таблице находится переменная, значение которой равно "ID последней ВЗЯТОЙ НА ОБРАБОТКУ записи основной таблицы". 

PS ORDER BY primary_key  не тормозит обработку ни в коей мере.

Вот, может кому пригодится.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Базы Данных | Следующая тема »


 




[ Время генерации скрипта: 0.0649 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.