SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 13.06.2018 09:33:47

activist
Участник
Зарегистрирован: 13.06.2018
Сообщений: 7

UPDATE на основе SELECT из той же таблицы

Приветствую.

Подскажите пожалуйста, есть ли возможность заставить такой запрос работать в mysql ?

UPDATE test SET ts={timestamp}, stamp='{stamp}' WHERE id IN (SELECT id FROM test ORDER BY ts ASC LIMIT 1000)

сейчас получаю такую ошибку
#1235 - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery

может есть какой-то лайфхак и можно как-то переписать запрос что бы работал?

Спасибо!

Неактивен

 

#2 13.06.2018 09:38:55

klow
Старожил
Зарегистрирован: 06.12.2014
Сообщений: 354

Re: UPDATE на основе SELECT из той же таблицы

Можно конечно извращаться, но лучше обновить версию MySql

Неактивен

 

#3 13.06.2018 09:45:29

activist
Участник
Зарегистрирован: 13.06.2018
Сообщений: 7

Re: UPDATE на основе SELECT из той же таблицы

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

Неактивен

 

#4 13.06.2018 09:54:58

klow
Старожил
Зарегистрирован: 06.12.2014
Сообщений: 354

Re: UPDATE на основе SELECT из той же таблицы

Вроде в 5.7 тоже не работает.
Вариант IN (SELECT ID FROM (SELECT id FROM test ORDER BY ts ASC LIMIT 1000) t)
Или можно создать временную таблицу
Или UPDATE test join (SELECT id FROM test ORDER BY ts ASC LIMIT 1000) t on test.id=t.id

Неактивен

 

#5 13.06.2018 10:27:39

activist
Участник
Зарегистрирован: 13.06.2018
Сообщений: 7

Re: UPDATE на основе SELECT из той же таблицы

klow, премного благодарен!
IN (SELECT ID FROM (SELECT id FROM test ORDER BY ts ASC LIMIT 1000) t)
заработал! хоть я и не понимаю почему такой вариант работает, а первоначальный нет
А какой из приведенных вами альтернатив вы считаете лучшей?

p.s ну тогда уж и вопрос в догонку ...

У меня есть таблица (пускай будет все тот же test) в которой около 500 тыс записей. Есть многопоточное клиентское приложение, которое берет порции данных из этой таблицы. Каждый поток должен взять 1000 выбранных строк и работать с ними. Одинаковые строки потоки брать не должны! Строки условно говоря берутся "по кругу", хотя я понимаю что в терминах субд так видимо не очень корректно говорить.
Собственно для этого мне и нужен вышеуказанный запрос, что бы каждый поток приложения генерировал свой уникальный id (в стартпосте я назвал его stamp) и пометил им строки которые выбрались в селекте (ну и время когда их взяли, конечно, что бы все было "по кругу"). Одним запросом хотел именно что бы не созлдавать временную таблицу.

Вопрос - нужно ли дополнительно использовать лок для таблицы или такой update на основе селекта в одном запросе обепечит некий построчный лок, который позволит быть уверенными что между селектом (отбирающим нужные строки) и апдейтом (помечающим их_ никто другой не возьмет ту же строку?

Неактивен

 

#6 13.06.2018 10:45:45

klow
Старожил
Зарегистрирован: 06.12.2014
Сообщений: 354

Re: UPDATE на основе SELECT из той же таблицы

Тут на форуме была статься по этому поводу, можно поискать, а если кратко, то в этом случае создается временная таблица и туда заносяться результаты подзапроса, а не производиться выборка из таблицы в момент самого запроса.

А какой из приведенных вами альтернатив вы считаете лучшей?

. Особой разницы я не вижу. Думаю, любой способ можно использовать какой Вам больше по душе. Я бы использовал 3-ий, как наиболее наглядный. Но если нужны детали, то лучше найти статью, там все доходчиво и понятно изложено.

p.s ну тогда уж и вопрос в догонку ...

Я недавно видел хорошую статься по этому поводу. Там все решается стандартными средствами СУБД,  но там используется, вроде, последняя версия - Вас, я так понял, это не устроит.
Правильно ли я понял, что выбираются 1000 строк, их помечаете, а после над ними работаете? По результатам работы отметку снимаете. Если нет, то не понимаю как решается вопрос с блокировками.

Неактивен

 

#7 13.06.2018 11:08:25

activist
Участник
Зарегистрирован: 13.06.2018
Сообщений: 7

Re: UPDATE на основе SELECT из той же таблицы

Да, последняя версия к сожалению не устроит.
Дело в том что пользователи приложения сами дополнительно ставят вэбсервер и mysql к себе на машину... естественно что для большинства это вообще что-то за пределами понимания, поэтому им предлагается ставить OpenServer, где в принципе все работет из коробки ... там можно выбирать версию mysql, но доступны лишь 5.1.73 / 5.5.58 / 5.6.38 / 5.7.20;

А так да, идея именно в пометке строк с которыми работает каждый конкретный поток клиентского приложения.
Каждый поток сгенерил свой уникальный stamp, выбрал строки с которыми дольше всего никто не работал (по сути это и есть "по кругу"), пометил их (заапдейтил stamp) и время обновил.
Отметку (stamp) в конце не обнуляю ... порции строк все равно берутся на основе времени (ORDER BY ts ASC), а не метки ... просто когда эти строки возьмутся в следующий раз, им присвоится новый stamp

Я вот и думаю, нужно ли лочить таблицу во время выбора порции строк и их пометки ...

Неактивен

 

#8 13.06.2018 11:45:31

klow
Старожил
Зарегистрирован: 06.12.2014
Сообщений: 354

Re: UPDATE на основе SELECT из той же таблицы

Я с подобными задачами не сталкивался, поэтому могу нюансов не знать, но думаю, этого достаточно.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson