powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
25 сообщений из 85, страница 1 из 4
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617686
useronforum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте.

Есть большая база данных MySQL
(записей до 10000, но есть большие BLOB-поля, которые нужно изменять,
поэтому база занимает на диске больше 3 Гб).

Нужно реализовать чтение всех записей таблицы
и БЫСТРОЕ изменение BLOB-поля многих записей.


ОБЯЗАТЕЛЬНОЕ ТРЕБОВАНИЕ:
Никакие компоненты для работы с БД, такие как DataSet не используются
(как здесь http://www.delphikingdom.com/asp/articles_forum.asp?ArticleID=1318 ),
поэтому метод Edit стандартных компонентов для редактирования
текущей записи использовать не получается,
то есть можно использовать MySQL.Query(...) и MySQL.ExecSQL(...).

===
Задачу я решил, но моё решение работает очень медленно:
за 12 часов обработалось примерно 10% базы данных.
И во время работы программы другие программы не могут нормально работать
с этой базой данной, так как всё тормозит
(систему нагружает MySQL - его процесс занимает почти всё процессорное время,
моя программа занимает до 5%).

Прошу предложить оптимизацию моего решения:

Код: pascal
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.
  
offset1 := 0; // смещение в результатах поиска

// если использовать "SELECT *"  без "LIMIT 10", 
// то программе не хватает памяти и она завершается с ошибкой

repeat
  query_result := MySQL.Query('SELECT * FROM MyTable LIMIT 10 OFFSET ' + IntToStr(offset1));

  if (query_result = nil) or (query_result.RecordCount = 0) then Break;

  while query_result.FetchRow do // проходим по записям
  begin
    mypointer := query_result.ValueByName['IMAGE']; // получили ссылку на BLOB поле

    // далее загружаем BLOB-поле в MemoryStream, обрабатываем и
    // в новую переменную NewBLOB помещаем новое значение BLOB

    // теперь запишем новое значение BLOB в поле
    // (каждая запись уникальна по паре значений CODE и NUM)

    // СКОРЕЕ ВСЕГО ИМЕННО ЗДЕСЬ НУЖНА ОПТИМИЗАЦИЯ !!!

    // я не знаю как изменить текущую запись, поэтому изменение делаю так:
    MySQL.ExecSQL('UPDATE MyTable SET MyTable.IMAGE="' + NewBLOB +
                  '" WHERE CODE = ' + query_result.ValueByName['CODE'] +
                  ' and NUM = ' + query_result.ValueByName['NUM']);

    offset1 := offset1 + 10;

  until (query_result.RecordCount = 0);
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617698
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это Delphi?
MySQL.Query - Это что такое?
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617710
useronforum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторЭто Delphi?
Delphi, но вопрос по правильности SQL-запросов на изменение BLOB-поля текущей записи.

var MySQL: IMySQL;

Подключаемые файлы брал здесь:
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1318

авторMySQL.Query - Это что такое?
SQL-запрос к базе данных
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617723
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имхо, у вас большая часть времени бессмысленно теряется в OFFSET-ах.
И, кстати, LIMIT без ORDER BY - рулетка. Рискуете некоторые записи два раза обработать, а некоторые ни разу.

Я бы сделал так:

Цикл по запросу вида
Код: sql
1.
SELECT CODE, NUM FROM MyTable ORDER BY CODE, NUM

до Eof.

В цикле запросы:
Код: sql
1.
SELECT IMAGE FROM MyTable WHERE CODE=... AND NUM=...

Код: sql
1.
UPDATE MyTable SET MyTable.IMAGE=... WHERE CODE=... AND NUM=...



Обязательно должен быть индекс из полей CODE, NUM. В данном случае порядок полей в индексе не важен. Для других задач может быть важен.
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617728
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
useronforumавторЭто Delphi?
Delphi, но вопрос по правильности SQL-запросов на изменение BLOB-поля текущей записи.

var MySQL: IMySQL;

Подключаемые файлы брал здесь:
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1318

авторMySQL.Query - Это что такое?
SQL-запрос к базе данных

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

то похоже я тоже не умею в базе строчку обновить. :)
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617748
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а вообще, здаёться мне лучше будет так

1)код который выгрузит нам нужные блоб поля в файлы на шдд
2)код на делфи обрабатывает эти файлы, и чтото там меняет сохраняя

3)потом идёт серия апдейтов указывая вкачестве значения поля LOAD FILE fname

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

под словом файл, имееться ввиду любая ересь, с которой сможет работать мускл по типу
SELECT INTO FILE LOAD FROM FILE но скорей всего это будет действительно физический файл на шдд.

обход записей в базе для обработки, обычно делаеться либо курсором либо по типу описано выше.

ибо
не будете же вы
ни молиться чтоб никто в базу ничего не вставил /не удалил
ни блокировать всю базу на время этой обработки

любые селекты что вы изобретаете, не дадут ожидаемый результат если появяться новые записи, или удаляться старые. либо курсор, либо снимок базы но не надеяться на богов.
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617754
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex5646574987654531)код который выгрузит нам нужные блоб поля в файлы на шдд
2)код на делфи обрабатывает эти файлы, и чтото там меняет сохраняяЗачем промежуточное сохранение в файл? это же утроение физического ввода-вывода.
Раз уж прочитали из MySQL BLOB в память, то в памяти его и обрабатывать.

alex564657498765453если действительно хочеться оптимизировать... то надо избежать конвертаций бинарных данных в строку и обратно, как на стороне мускла так и на стороне клиента.Вроде бы BLOB-ы такой конвертацией не страдают...
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617774
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoft,

серьёзно ??? а зачем мы при соединении указываем кодовую страницу??? не потому ли что общение исключительно текстом!

база из бинарника делает

100ef67a7c7b

мы врядли обрабатывая блоб, обрабатываем его имено в ввиде такой строки. идёт обратное преобразование в цепочку байт

цепочку байт обрабатываем, формируем ТЕКС СКЛ ! обратно конвертация, кидаем в базу, там обратная конвертация.


про файлы, я не говорю что файлы быстрее, я говорю что ему один чорт надо все сначало выгрузить, обрабатывать, потом загружать назад, а не надеяться на чесное пионерское, что за эти 10 часов никто не поменяет число записей в таблице(вставка, удаление)

и раз уж их все всторону смещать, я бы делал имено в файлы. хотя ... он сказал 10000 записей и 3гектара база, значит один блоб гдето 300кб... мдя...файлы плохая затея.

ЗЫ
а вообще меня смущает постановка вопроса... blob тип это как бы не для того чтоб брать и 10 байт в нём менять.
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617778
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex564657498765453а зачем мы при соединении указываем кодовую страницу???Для строковых полей.
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617785
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoft,

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

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

ЗЫ не зря же много когда используеться имено временный файл - это тогда, когда обьёмы не малые(не 2,4,8,16 байт) - когда есть шанс бросания в своп и обратно, а это куда медленее чем самому красивенько кидать в файл, потом считывать)
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617794
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftalex564657498765453а зачем мы при соединении указываем кодовую страницу???Для строковых полей.

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

пойми мне правильно, сказать что мы указываем кодировку только для текстовых полей, тоже самое что мы указываем в штмл кодировку только для - содержания тегов, значений текстовых переменых. согласен фиг доколупаешься, ибо действительно только они будут не верно интерпретированы. но всётаки щитаю что кодировка указываеться для протокола, который основан на передаче текста!
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617805
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex564657498765453скорей всего в своп повалиться...откуда эти фантазии про своп, если там средний размер блоба 300Кбайт ?
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617814
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
оптимизировать можно исключив limit
и выбирать по одной записи, лимит может вносить существенное торможение
даже при увеличении обращений к серверу это сэкономит время

чтои советует miksoft
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617834
useronforum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторЯ бы сделал так:

Цикл по запросу вида
SELECT CODE, NUM FROM MyTable ORDER BY CODE, NUM
до Eof.
Действительно SELECT "CODE, NUM" выдаст записи без поля BLOB.
Возможно оперативной памяти хватит.
Надо попробовать.

Но если ключевые поля не эти, то сработает ли "ORDER BY CODE, NUM"?

авторВ цикле запросы:
SELECT IMAGE FROM MyTable WHERE CODE=... AND NUM=...
UPDATE MyTable SET MyTable.IMAGE=... WHERE CODE=... AND NUM=...
Не понимаю зачем первая строка,
ведь вторая строка не использует результат первой?
Или это один запрос?

авторОбязательно должен быть индекс из полей CODE, NUM. В данном случае порядок полей в индексе не важен. Для других задач может быть важен.
Базу данных не я проектировал.
Какие в ней ключи не знаю.
Структуру базы данных изменять нельзя.

авторИмхо, у вас большая часть времени бессмысленно теряется в OFFSET-ах.
Без них никак.
Если использовать "SELECT *" без "LIMIT 10",
то программе не хватает памяти и она завершается с ошибкой

авторИ, кстати, LIMIT без ORDER BY - рулетка.
Возможно важное замечание.
Но разве записи выдаются не в порядке добавления в таблицу?

авторРискуете некоторые записи два раза обработать, а некоторые ни разу.
Это не проблема. Я могу программу 10 раз запустить.

Тем более, что после изменения записи, записи повторно быстро обрабатываются.
(После обработке обычно их размер уменьшается в разы)

автора вообще, здаёться мне лучше будет так

1)код который выгрузит нам нужные блоб поля в файлы на шдд
2)код на делфи обрабатывает эти файлы, и чтото там меняет сохраняя
Через файлы ещё медленнее.

автор3)потом идёт серия апдейтов указывая вкачестве значения поля LOAD FILE fname
Приведите пример SQL запроса с загрузкой файла в BLOB-поле.

Подозреваю, что возможны ошибки SQL или зависания,
так как моя программа отправит 1000 запросов
на изменение BLOB-полей из 1000 файлов по 1 Мб,
и что в каком порядке и когда изменится не известно.

авторесли действительно хочеться оптимизировать... то надо избежать конвертаций бинарных данных в строку и обратно, как на стороне мускла так и на стороне клиента.
Это работает быстро.
Систему нагружает MySQL - его процесс занимает почти всё процессорное время,
моя программа занимает до 5%

авторобход записей в базе для обработки, обычно делаеться либо курсором либо по типу описано выше.
Как это?

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

Проблема в том, что сейчас программа не может успеть за ночь.

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

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

автора вообще меня смущает постановка вопроса... blob тип это как бы не для того чтоб брать и 10 байт в нём менять.
Меняется не 10 байт, а абсолютно все байты и длина всего BLOB.
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617855
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторВ цикле запросы:
SELECT IMAGE FROM MyTable WHERE CODE=... AND NUM=...
UPDATE MyTable SET MyTable.IMAGE=... WHERE CODE=... AND NUM=...

Не понимаю зачем первая строка,
ведь вторая строка не использует результат первой?
Или это один запрос?



гыыыы
первая выбирает данное
второе записывает изменённое данное

CODE=... AND NUM=... - фильтрация данных для выбора и для записи

limit забирает всё время
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617868
useronforum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторавтор
Я бы сделал так:

Цикл по запросу вида
SELECT CODE, NUM FROM MyTable ORDER BY CODE, NUM
до Eof.

Действительно SELECT "CODE, NUM" выдаст записи без поля BLOB.
Но мне нужно поле BLOB , чтобы на основании его рассчитать новое значение.

А если одним SELECT получить CODE и NUM,
а вторым получать по ним IMAGE,
то не потеряется ли результат первого SELECT (если всё-таки использовать OFFSET),
даже если я для результатов первого и второго SELECT заведу разные переменные?

автороптимизировать можно исключив limit
и выбирать по одной записи, лимит может вносить существенное торможение
даже при увеличении обращений к серверу это сэкономит время
Как без "LIMIT 1" с помощью "SELECT" получить 1 запись?
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617873
useronforum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И есть ли в SQL команда на изменение i-ой записи в таблице без "WHERE"?
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617882
useronforum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И в какой момент данные передаются в программу:
автор
query_result := MySQL.Query('SELECT * FROM MyTable LIMIT 10 OFFSET ' + IntToStr(offset1));
или
авторquery_result.FetchRow
?
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617888
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
useronforum,

хм...если тебя устроит перенести логику на мускл, так напиши хранимку которая сделает нужные замены с блобами...

всётаки раскажи, что за замены ты с блобом делаешь, что надо их хранить в базе а не в файлах на шдд, и что нужны такие замены....
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617896
useronforum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Базу данных не я проектировал.
Структуру базы данных изменять нельзя и другие изменения мне вносить нельзя.
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617903
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
useronforumНо если ключевые поля не эти, то сработает ли "ORDER BY CODE, NUM"?Сработает, почему нет?
Хотя если индекс есть, то сработает значительно быстрее.
useronforumСтруктуру базы данных изменять нельзя.Индекс - это не структура.
Проверьте, возможно, индекс уже есть.
Без него даже ваш изначальный апдейт будет работать неразумно долго.
useronforumавторИмхо, у вас большая часть времени бессмысленно теряется в OFFSET-ах.
Без них никак.
Если использовать "SELECT *" без "LIMIT 10",
то программе не хватает памяти и она завершается с ошибкойНе знаю как у используемого компонента, а у нормальных Query можно ограничить размер потребляемой памяти буфером хоть на одну запись. Так что лимит сам по себе не нужен.
И, кстати, не пользуйтесь звездочкой в боевых запросах. Лишние поля таскать ни чему.
useronforumавторВ цикле запросы:
SELECT IMAGE FROM MyTable WHERE CODE=... AND NUM=...
UPDATE MyTable SET MyTable.IMAGE=... WHERE CODE=... AND NUM=...
Не понимаю зачем первая строка,
ведь вторая строка не использует результат первой?
Или это один запрос?Нет, это два запроса. Первый читает блоб, потом ваша обработка, второй сохраняет блоб.
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617905
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторДействительно SELECT "CODE, NUM" выдаст записи без поля BLOB.

расшифруй
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617920
useronforum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Про ключи узнал:
PRIMARY KEY (`CODE`,`NUM`,`DATE1`).


авторНе знаю как у используемого компонента, а у нормальных Query можно ограничить размер потребляемой памяти буфером хоть на одну запись. Так что лимит сам по себе не нужен.
Программа начинала занимать 900Мб и т.д. пока "Out of memory" не появилось.

авторавторавтор
Действительно SELECT "CODE, NUM" выдаст записи без поля BLOB.
расшифруй
IMAGE - BLOB-поле, которое занимает много байт.
Если его в SELECT не ставить, то меньше информации передаётся SELECT.
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617924
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
useronforumПро ключи узнал:
PRIMARY KEY (`CODE`,`NUM`,`DATE1`).О, это хорошо. Отдельный индекс создавать не надо.
useronforumавторНе знаю как у используемого компонента, а у нормальных Query можно ограничить размер потребляемой памяти буфером хоть на одну запись. Так что лимит сам по себе не нужен.
Программа начинала занимать 900Мб и т.д. пока "Out of memory" не появилось.Смотрите свойства компонента. Например, Unidirectional.
Да и без этого, 10000 полей `CODE` и `NUM` займут копейки по сравнению с 900Мб.
...
Рейтинг: 0 / 0
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
    #38617952
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторIMAGE - BLOB-поле, которое занимает много байт.
Если его в SELECT не ставить, то меньше информации передаётся SELECT.

а если ничего не ставить - ваще места буде дофига

тебе ж разжевали

Нет, это два запроса. Первый читает блоб, потом ваша обработка, второй сохраняет блоб.

а если и при этом у тебя будет переполнение памяти - зачит при обработке блоба ты не правильно работаешь с памятью
видимо в цикле создаются новые переменные, а не используются прежние
...
Рейтинг: 0 / 0
25 сообщений из 85, страница 1 из 4
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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