powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Ускорение удаления большого количества записей
25 сообщений из 35, страница 1 из 2
Ускорение удаления большого количества записей
    #40117315
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброго времени суток. Вылезла следующая проблема. Есть таблица примерно на 5.5 миллионов записей. Как выяснилось, подавляющее большинство этих записей лишние и требуют удаления. По довольно сложному алгоритму эти записи определяются и создается скрипт на их удаление. Навскидку взят метод формирования списка запросов на удаление 1000 записей в каждом: Delete From T1 Where ID In (ID1, ID2, ... ID1000) - естественно по первичному ключу. Запустил это скрипт на относительно производительном линуксовом серваке - выполнение идет уже более получаса. Отсюда вопрос: можно ли как-то оптимизировать и ускорить этот процесс?
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117321
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
S_Gur
Доброго времени суток. Вылезла следующая проблема. Есть таблица примерно на 5.5 миллионов записей. Как выяснилось, подавляющее большинство этих записей лишние и требуют удаления. По довольно сложному алгоритму эти записи определяются и создается скрипт на их удаление. Навскидку взят метод формирования списка запросов на удаление 1000 записей в каждом: Delete From T1 Where ID In (ID1, ID2, ... ID1000) - естественно по первичному ключу. Запустил это скрипт на относительно производительном линуксовом серваке - выполнение идет уже более получаса. Отсюда вопрос: можно ли как-то оптимизировать и ускорить этот процесс?


Т.е. удаление 1000 записей идет уже 30 минут? Это что-то не то.
У этой таблицы есть связанные таблицы по ПК-ФК? триггеры?
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117361
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
S_Gur,

Вероятно будет быстрее нужные записи скопировать в новую таблицу, а старую грохнуть целиком.
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117363
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин, вся операция - удаление 5.5 миллионов записей - заняла больше часа. Для промышленного сервера это в моем случае неприемлемо
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117383
Gluck99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
S_Gur
По довольно сложному алгоритму эти записи определяются и создается скрипт на их удаление.
Перенести ваш "довольно сложный алгоритм" на серверную часть в хранимые процедуры, которые будут формировать временную таблицу с ID для удаления. Далее удалять через JOIN, без всяких IN(). Фактически, используя IN(), сервер по вашему скрипту выполняет 5 миллиардов (на таблице в 5.5 миллионов записей) лишних действий, что логично вытекает в такое время работы.
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117398
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Gluck99
S_Gur
По довольно сложному алгоритму эти записи определяются и создается скрипт на их удаление.
Перенести ваш "довольно сложный алгоритм" на серверную часть в хранимые процедуры, которые будут формировать временную таблицу с ID для удаления. Далее удалять через JOIN, без всяких IN(). Фактически, используя IN(), сервер по вашему скрипту выполняет 5 миллиардов (на таблице в 5.5 миллионов записей) лишних действий, что логично вытекает в такое время работы.


К сожалению, этот вариант мне вряд ли подойдет. Несложно написать хранимую процедуру, но алгоритм подразумевает проверку каждой записи, сверку ее полей с полями предыдущей и решение, нужно ли ее удалять (при этом переписав некоторые поля в ту самую предыдущую запись). Программа на Дельфях работает часа полтора, вряд ли процедура с курсорами, обрабатывающими 5 миллионов записей отработает намного быстрее, но при этом клиентская программа берет записи частями и почти не нагружает сервер. В итоге по времени в самом лучшем случае выйдет так на так. Да и формирование временной таблицы на несколько миллионов записей (пусть даже и с одним полем) - тоже процесс не быстрый... Скорее всего, решение будет в написании другой клиентской программы, которая будет выполнять эти запросы по одному с интервалом в несколько секунд между ними. Это будет, конечно, гораздо дольше, но зато вряд ли сильно нагрузит сервер
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117410
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
S_Gur,

ты бы попробовал, прежде чем делать такие выводы
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117413
PizzaPizza
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
S_Gur
Программа на Дельфях работает часа полтора, вряд ли процедура с курсорами, обрабатывающими 5 миллионов записей отработает намного быстрее, но при этом клиентская программа берет записи частями и почти не нагружает сервер. В итоге по времени в самом лучшем случае выйдет так на так. Да и формирование временной таблицы на несколько миллионов записей (пусть даже и с одним полем) - тоже процесс не быстрый... Скорее всего, решение будет в написании другой клиентской программы, которая будет выполнять эти запросы по одному с интервалом в несколько секунд между ними. Это будет, конечно, гораздо дольше, но зато вряд ли сильно нагрузит сервер


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

S_Gur
Отсюда вопрос: можно ли как-то оптимизировать и ускорить этот процесс?

Выборка 5 миллионов записей сплошняком не может занять 30 минут. Ваша проблема, очень вероятно, в алгоритме определения "лишних" записей, который либо читает еще миллионы записей из других таблиц и делает кучу вычислений, либо/и это все не оптимизировано совершенно. Ищите способы оптимизации вашего алгоритма.
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117414
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PizzaPizza, вы невнимательно прочли мой первый пост. Алгоритм определения удаляемых записей тут ни при чем. Я просил совета именно по ускорению самого скрипта на удаление записей. Время на анализ данных и создание этого скрипта мне неважно - скрипт уже создан и пересоздать его при необходимости в более оптимальном варианте не составляет проблем. Мне нужен только конечный результат - максимально быстрое удаление уже найденных конкретных записей
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117416
Gluck99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
S_Gur
Я просил совета именно по ускорению самого скрипта на удаление записей. Время на анализ данных и создание этого скрипта мне неважно - скрипт уже создан и пересоздать его при необходимости в более оптимальном варианте не составляет проблем.
Не хотите грамотно делать - делайте пачку запросов по 10'000 штук, но без IN(). Т.е. один ID - один запрос.
Код: sql
1.
2.
3.
4.
DELETE FROM MyTable WHERE ID = 1;
DELETE FROM MyTable WHERE ID = 2;
DELETE FROM MyTable WHERE ID = 3;
-- и т.д.
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117419
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Gluck99, если так оформлять пачки запросов, то что должно быть между ними? Или вообще отказаться от понятия пачек и выполнять все удаления подряд по одной записи?
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117459
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
S_Gur
Мне нужен только конечный результат - максимально быстрое удаление уже найденных конкретных записей

Удаление по одной записи - никак не ускорить. Только замедлить. Например, отдельным запросом на каждую запись.
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117473
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov, поэтому я формировал запросы на удаление сразу 1000 записей. Но вот тут знающие товарищи говорят, что это не есть правильно
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117475
Gluck99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
S_Gur
Мне нужен только конечный результат - максимально быстрое удаление уже найденных конкретных записей

Удаление по одной записи - никак не ускорить. Только замедлить. Например, отдельным запросом на каждую запись.
100'000 записей удаляются по первичному ключу примерно за 6-7 секунд (сервер медленный публичный), на каждое удаление свой запрос. Таблица, конечно, небольшая, из трёх полей (ID, число и текст). Удаление 5.5 миллионов записей должно занимать несколько минут, а если сервер выделенный и мощный, как у ТС, то вообще никаких проблем быть не должно.
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117481
Gluck99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
S_Gur
Dimitry Sibiryakov, поэтому я формировал запросы на удаление сразу 1000 записей. Но вот тут знающие товарищи говорят, что это не есть правильно
Не есть правильно обрабатывать данные на клиенте, когда их предпочтительнее обрабатывать на сервере. Перенос на сервер алгоритма формирования строк на удаление даст прирост минимум в 10 раз, плюс непосредственно запрос на удаление ускорит само удаление раз в 100. И будет у вас всё выполняться секунды/минуты, а не часы. Бонусом снизится вероятность потери данных. Я понимаю, что на паскале писать приятнее и удобнее, но не получится одновременно и морковку съесть, и снеговику нос приделать.
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117488
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Gluck99, у меня получилось. Как минимум, определение подлежащих удалению записей не завесило на лишних 30-40 минут промышленный сервак. Я, кажется, вполне понятно объяснил довольно простую вещь - в вашем варианте выигрыш в скорости при удалении записей компенсируется проигрышем за счет времени выполнения их обработки. В конечном варианте у меня минут 20 на удаленном клиенте - на столь нелюбимом вами паскале - формируется скрипт, обрабатывая записи по частям и, соответственно, довольно слабо, периодически и на короткие сроки нагружая сервер, и еще минут 20 этот скрипт на сервере выполняется. При этом в системные логи MySQL падает 5 тысяч запросов, а не 5 миллионов. Вы почему-то считаете свои критерии разработки программ единственно верными, а это не так. Мне важно выполнить задачу так, чтобы 15000 клиентов, которые в режиме 24х7 обращаются к базе, не зависли на лишних полчаса, поэтому для меня вполне приемлемо выполнить часть работы на удаленном клиенте, пусть даже общее время несколько возрастет. Для общего развития рекомендую провести следующий опыт: написать хранимую процедуру, в которой открыть курсор на чтение 5 000 000 записей из 10-15 полей каждая и просто сравнить каждое из этих полей со значением из предыдущей записи (это только часть моей задачи), а после этого примерно 9 из 10 записей удалить. Вряд ли вы сумеете меня убедить, что весь этот процесс даже на мощном и не очень нагруженном сервере займет менее получаса. Для того, чтобы судить о способе выполнения задачи, надо как минимум знать ее постановку и требования к реализации. Ни о том, ни о другом вы не имеете ни малейшего понятия, поэтому вы при всем желании не можете судить, правильно ли я эту задачу решаю или нет. Я задал конкретный вопрос - как ускорить удаление записей, зная их первичные ключи. Как я определяю эти записи - мое личное дело, и время их определения - как я уже писал - не входит в процесс ускорения задачи. Формировать запросы на удаление по одной записи вместо 1000-х пакетов - это вполне логичный совет, я попробую (хотя подозреваю, что падение в системный лог 5 000 000 запросов вместо 5 000 тоже будет грузить сервер), а мой способ определения этих записей меня вполне устраивает
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117497
Gluck99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
S_Gur
Gluck99, у меня получилось.
Что получилось?

Вы кипятитесь напрасно, по всем признакам у вас "проблема XY" https://ru.wikipedia.org/wiki/Проблема_XY, отсюда и отношение. Может быть оно и не так, но пока выглядит именно так. Здесь вообще 90% вопросов задаются в этом контексте.

Что касается вашего супер-пупер алгоритма, то не исключено, что его можно облегчить, разбив на части и проведя предварительный отбор данных через insert/update select запрос. Можно добавить поле c признаком удаления. Расставить галочки, потом одним запросом удалить.

Я сам часто работаю на Delphi, поэтому замечание о паскале мимо.
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117507
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Gluck99, вы неправильно истолковали эти признаки. У меня проблема именно такая, какую я описал. И проблема эта уже решена - данные удалены в течение вполне приемлемых сроков - удаление выполнено минут за 15-20. Вы не ответили на мой вопрос: сколько времени займет выполнение хранимой процедуры, которая курсором обойдет 5 миллионов записей? И насколько она загрузит сервер? Я вам уже в третий раз объясняю: ускорение самого удаление записей по вашему методу влечет за собой увеличение общего времени выполнения всей задачи, причем именно на сервере, что мне никак не было нужно. Я вынес обработку записей и формирование скрипта на клиент и нисколько не сомневаюсь, что был прав. Вот формирование этого самого скрипта может быть выполнено несколькими вариантами и я искал лучший. С чего вы взяли, что апдейт 5 миллионов записей, чтобы выставить ту самую пометку на удаление, чтобы потом удалить эти самые 5 миллионов по выставленной пометке, будет выполняться намного быстрее? Как по мне, то в совокупности в лучшем случае те же яйца, только в профиль. Как ни крути, запросов будет именно столько, сколько вышло у меня - никак не меньше. Либо 5 миллионов апдейтов по одной записи по первичному ключу, чтобы выставить ваши галочки, и потом одним запросом удалить все записи с галочками, либо 5 миллионов делитов тех же записей по первичному ключу. Либо - в моем случае - 5 тысяч запросов - что на выставление галочек у 1000 записей по условию ID In (), что на удаление тех же самых записей по тому же условию. Как бы вы не извращались с алгоритмом выбора нужных записей, все это не сократит количество запросов для их удаления. Ни от одного из них никуда не денешься. Поэтому в любом случае скрипт удаления записей на сервере выполнится быстрее, чем то же удаление плюс предварительная выборка этих записей, выполняемые в рамках одной хранимой процедуры. И кто вам сказал, что мой алгоритм поиска удаляемых записей уже максимально не облегчен? Вы видели его реализацию?
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117533
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
S_Gur
и нисколько не сомневаюсь, что был прав.
с таким подходом отбивает всю охоту что-то советовать
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117551
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вадя, а вы отвечайте на вопрос, который был задан. Или не отвечайте, если неохота. Все очень просто
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117563
PizzaPizza
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
S_Gur
Я просил совета именно по ускорению самого скрипта на удаление записей. Мне нужен только конечный результат - максимально быстрое удаление уже найденных конкретных записей


Ну если у вас из каких то 5 м записей удаление происходит 30 минут любым способом, то вам просто необходим человек, который понимает в базах данных. Ибо очевидно, что там наклепал кто то такое что проще все переделать.

И да, если это одноразовая задача, то можно делать DELERE FROM WHERE = хоть раз в пол часа по одной строке. Если же это периодическая плановая процедура, то обратитесь к человеку который понимает в базах данных.
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117575
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PizzaPizza, да, это разовая задача. И я не пробовал пока удалять записи любым способом. Выполнялся скрипт, состоящий их запросов вида Delete From `tbStockItemsLog` Where `ID` In (ID1, ID2, ... ID1000). Насколько я понимаю, там должно было быть порядка 5000 с небольшим таких запросов. Таблица создана таким скриптом:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
Create Table If Not Exists `tbStockItemsLog`
(`biID` BigInt UnSigned Not Null Primary Key Auto_Increment Comment 'Уникальный идентификатор',
 `biIDMain` BigInt UnSigned Not Null Comment 'Идентификатор записи в основной таблице',
 `biFaceID` BigInt UnSigned Default 0 Not Null Comment 'Идентификатор контрагента (клиент)',
 `biClientID` BigInt UnSigned Default 0 Not Null Comment 'Идентификатор клиента',
 `biEmployeeID` BigInt UnSigned Default 0 Not Null Comment 'Идентификатор сотрудника',
 `biEquipmentID` BigInt UnSigned Default 0 Not Null Comment 'Идентификатор оборудования',
 `tiState` TinyInt Unsigned Default 0 Not Null Comment 'Состояние',
 `cMACAddress` Char(17) Default '…' Not Null Comment 'МАК Адрес',
 `vcSerialNum` VarChar(100) Default '…' Not Null Comment 'Серийный номер',
 `iAmount` Integer Default 1 Not Null Comment 'Количество',
 `dtDate` DateTime Not Null Comment 'Дата',
 `bIsRedMax` Boolean Default 1 Not Null Comment 'Признак собственности РедМакса',
 `vcRemark` VarChar(2000) Default '…' Not Null Comment 'Комментарий',
 `bIsDeletable` Boolean Default 0 Not Null Comment 'Признак запрещения удаления записи',
 `biChangerID` BigInt Default 0 Not Null Comment 'Идентификатор пользователя, выполнившего изменение',
 `vcNetName` VarChar(1000) Default '…' Not Null Comment 'Откуда производилось изменение',
 `dtDateBegin` DateTime Not Null Comment 'Начало действия изменений',
 `dtDateEnd` DateTime Default '2500-01-01 00:00:00' Not Null Comment 'Окончание действия изменений',
 `tiEditMode` TinyInt Unsigned Default 0 Not Null Comment 'Вид изменений: 0 - создание; 1 - изменение; 2 - удаление; 3 - восстановление')
ENGINE=InnoDB Default CharSet=utf8 Auto_Increment=0 Comment='Лог устройств';

# Создаем индексы

Create Index
  K_StockItemsLog_IDMain
On
  `tbStockItemsLog` (`biIDMain`);

Create Index
  K_StockItemsLog_ChangerID
On
  `tbStockItemsLog` (`biChangerID`);

Create Index
  K_StockItemsLog_DateBegin_DateEnd
On
  `tbStockItemsLog` (`dtDateBegin`, `dtDateEnd`);



Есть какие-то замечания? Что именно здесь "наклепано так, что нужно обратиться к специалисту по базам данных"? С удовольствием выслушаю любые замечания
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117589
PizzaPizza
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
S_Gur,

Я полагаю, что Where `ID` имеется ввиду Where `biID`

Глядя на вашу таблицу я вижу, что строка у вас занимает 4000 байт, что для 5 миллионов строк будет чуть меньше 20 мегабайт (с учетом 4х BigInt индексов и усушки утруски)

У меня возникает простой вопрос: что у вас с базой данных, когда на "промышленном сервере" ваши 20 мегабайт обрабатываются 30 минут.

Может у вас там куча триггеров, или foreign key на каждый ID который проверяется для каждой строки... Кто знает... специалист вероятно.
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117590
PizzaPizza
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PS.
"Насколько я понимаю, там должно было быть порядка 5000 с небольшим таких запросов"

У вас кластерный индекс по biID. Когда вы "пачками" удаляете из него, после каждой пачки ваши индексы перестраиваются (если я правильно понимаю InnoDB конечно) и у вас вся таблица физически может переписываться со всеми 4мя индексами на диске/памяти (сильно зависит от движка). Все это - накладные расходы на "пачечное" удаление. Хотя опять же, 20 мегабайт это ничто для базы данных.
...
Рейтинг: 0 / 0
Ускорение удаления большого количества записей
    #40117597
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PizzaPizza
строка у вас занимает 4000 байт, что для 5 миллионов строк будет чуть меньше 20 мегабайт
Гигабайт... а так - да.
...
Рейтинг: 0 / 0
25 сообщений из 35, страница 1 из 2
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Ускорение удаления большого количества записей
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]