|
Оптимизация параллельной выборки
|
|||
---|---|---|---|
#18+
Приветствую, уважаемые разработчики! Спасибо за ваше внимание к моему вопросу! У меня есть таблица, в которую постоянно помещается очередь заданий для обработки: TABLE "users_activity" (MyISAM) "id" (INT 11) PRIMARY KEY, "action" (VARCHAR 50), "flag" (INT 1) INDEX Здесь "action" - это просто название обработчика (функции), который нужно произвести (обрезка загруженного видео, оптимизация фотографии и т.п.) А "flag" может быть 0 - задание в очереди, 1 - обрабатывается в данный момент, 2 - готово. Эта таблица обрабатывается по расписанию несколькими скриптами (параллельно с нескольких серверов), где каждый скрипт берет запись и выполняет ее. 1. Выбирает запись и ставит флаг "в обработке" (чтобы предотвратить параллельное выполнение задачи, которое уже в очереди). Код: sql 1.
2. Обрабатывает 3. И обновляет флаг, что задача завершена. Код: sql 1.
Проблема в том, что 1 запрос на выборку уникальной очередной записи часто подвисает на 5-7 секунд. Код: sql 1.
id>=298122 - для ускорения запроса сохраняю каждый последний успешный id и добавляю его в подзапрос SELECT. Кроме того, в самой таблице ранее выполненные (flag=1) задания регулярно удаляются, т.е. количество строк в таблице не является безграничным, поддерживается в диапазоне 0-3000 строк одновременно. Но увы... Код: sql 1.
Ищу любые идеи оптимизации... ... |
|||
:
Нравится:
Не нравится:
|
|||
06.08.2020, 13:50 |
|
Оптимизация параллельной выборки
|
|||
---|---|---|---|
#18+
авторRows_examined: 1417 индексов нет? ... |
|||
:
Нравится:
Не нравится:
|
|||
06.08.2020, 13:56 |
|
Оптимизация параллельной выборки
|
|||
---|---|---|---|
#18+
ScareCrow, "id" (INT 11) PRIMARY KEY, "flag" (INT 1) INDEX ... |
|||
:
Нравится:
Не нравится:
|
|||
06.08.2020, 14:14 |
|
Оптимизация параллельной выборки
|
|||
---|---|---|---|
#18+
e_moon "flag" может быть 0 - задание в очереди, 1 - обрабатывается в данный момент, 2 - готово. Я бы сделал: Каждый обработчик регистрируется в системе, получая уникальный номер, и потом уже работает. В поле флага: NULL - задание в очереди, 0 - задание обработано, больше нуля - идентификатор обработчика, который обрабатывает задание в данный момент. Соответственно резервирование выполняется простейшим Код: sql 1. 2. 3. 4.
После чего зарезервированное задание забирается на обработку Код: sql 1. 2. 3.
Если идентификатор задания получен - обрабатываем. Если же произойдёт одновременное резервирование, и задание будет "перехвачено" (записанное значени flag перезаписано параллельным запросом), второй запрос не вернёт записи, и обработчик снова попробует зарезервировать себе запись. e_moon Проблема в том, что 1 запрос на выборку уникальной очередной записи часто подвисает на 5-7 секунд. А что Вы хотите? MyISAM - так что каждый из запросов лочит всю таблицу. Перейдите на InnoDB. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.08.2020, 14:16 |
|
Оптимизация параллельной выборки
|
|||
---|---|---|---|
#18+
Akina, Спасибо за подробный ответ! Честно говоря, я был уверен что делаю то же самое, только обернуто в один запрос. Выбираю запись и запоминаю ее id, дальше обновляю флаг по этому id. Т.к. MyISAM не поддерживает транзакции, то это единственный выход, который я нашел. Но Ваша идея интересная, в случае с InnoDB я еще могу использовать транзакцию, в которой будут и SELECT и UPDATE, как Вы предлагаете. Возможно, это решит проблему конкурентных запросов. Но по поводу InnoDB... У меня сейчас есть другая сторона медали - это еще INSERT-ы в эту таблицу. В MyISAM есть возможность INSERT DELAYED IGNORE, но в InnoDB, похоже, этого нет. Обычный INSERT в случае InnoDB не будет тормозить? ... |
|||
:
Нравится:
Не нравится:
|
|||
06.08.2020, 14:55 |
|
Оптимизация параллельной выборки
|
|||
---|---|---|---|
#18+
Да, еще добавил составной индекс: Код: sql 1.
Но разницы не заметно:( ... |
|||
:
Нравится:
Не нравится:
|
|||
06.08.2020, 18:28 |
|
Оптимизация параллельной выборки
|
|||
---|---|---|---|
#18+
сильон вряд ли такой индекс будет использоваться. смотри планы запроса. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.08.2020, 11:09 |
|
Оптимизация параллельной выборки
|
|||
---|---|---|---|
#18+
ScareCrow сильон вряд ли такой индекс будет использоваться. смотри планы запроса. Кстати, да. А вот с обратным порядком полей (id, flag) для запроса Код: sql 1.
индекс будет вполне полезным, да еще и покрывающим. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.08.2020, 12:10 |
|
Оптимизация параллельной выборки
|
|||
---|---|---|---|
#18+
paver А вот с обратным порядком полей (id, flag) для запроса Код: sql 1.
индекс будет вполне полезным, да еще и покрывающим. Правда, запрос при этом надо конвертировать в Код: sql 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
07.08.2020, 13:33 |
|
Оптимизация параллельной выборки
|
|||
---|---|---|---|
#18+
Спасибо всем за помощь. Финальный SQL: Код: sql 1.
Explain показывает Range. В общем, убрав только ORDER BY удалось добиться хорошего результата и скорости. В принципе, в моем случае очередность не столь критична и этим удалось пренебречь. Код: sql 1.
Как ни странно, но вариант с MIN(id) оказался хуже, Explain показывает All. Но для теста я его оставил и он вызывается 1 на 100 интераций где-то, попробую его тоже поотслеживать на деле и сравню, когда будут данные. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.08.2020, 15:42 |
|
|
start [/forum/topic.php?fid=47&fpage=17&tid=1828406]: |
0ms |
get settings: |
10ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
56ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
60ms |
get tp. blocked users: |
2ms |
others: | 272ms |
total: | 434ms |
0 / 0 |