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

Есть большая база данных 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
17.04.2014, 15:58:25
    #38617698
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
Это Delphi?
MySQL.Query - Это что такое?
...
Рейтинг: 0 / 0
17.04.2014, 16:11:17
    #38617710
useronforum
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
авторЭто Delphi?
Delphi, но вопрос по правильности SQL-запросов на изменение BLOB-поля текущей записи.

var MySQL: IMySQL;

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

авторMySQL.Query - Это что такое?
SQL-запрос к базе данных
...
Рейтинг: 0 / 0
17.04.2014, 16:20:43
    #38617723
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
Имхо, у вас большая часть времени бессмысленно теряется в 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
17.04.2014, 16:24:38
    #38617728
alex564657498765453
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
useronforumавторЭто Delphi?
Delphi, но вопрос по правильности SQL-запросов на изменение BLOB-поля текущей записи.

var MySQL: IMySQL;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

100ef67a7c7b

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

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


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

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

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

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

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

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

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

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

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

Цикл по запросу вида
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
17.04.2014, 17:40:28
    #38617855
вадя
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
авторВ цикле запросы:
SELECT IMAGE FROM MyTable WHERE CODE=... AND NUM=...
UPDATE MyTable SET MyTable.IMAGE=... WHERE CODE=... AND NUM=...

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



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

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

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

Цикл по запросу вида
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
17.04.2014, 17:53:05
    #38617873
useronforum
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
И есть ли в SQL команда на изменение i-ой записи в таблице без "WHERE"?
...
Рейтинг: 0 / 0
17.04.2014, 18:00:23
    #38617882
useronforum
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
И в какой момент данные передаются в программу:
автор
query_result := MySQL.Query('SELECT * FROM MyTable LIMIT 10 OFFSET ' + IntToStr(offset1));
или
авторquery_result.FetchRow
?
...
Рейтинг: 0 / 0
17.04.2014, 18:04:12
    #38617888
alex564657498765453
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
useronforum,

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

всётаки раскажи, что за замены ты с блобом делаешь, что надо их хранить в базе а не в файлах на шдд, и что нужны такие замены....
...
Рейтинг: 0 / 0
17.04.2014, 18:10:23
    #38617896
useronforum
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
Базу данных не я проектировал.
Структуру базы данных изменять нельзя и другие изменения мне вносить нельзя.
...
Рейтинг: 0 / 0
17.04.2014, 18:14:18
    #38617903
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
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
17.04.2014, 18:15:46
    #38617905
вадя
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
авторДействительно SELECT "CODE, NUM" выдаст записи без поля BLOB.

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


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

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

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

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

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

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


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