|
|
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
Здравствуйте. Есть большая база данных 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 15:47:14 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
Это Delphi? MySQL.Query - Это что такое? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 15:58:25 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
авторЭто Delphi? Delphi, но вопрос по правильности SQL-запросов на изменение BLOB-поля текущей записи. var MySQL: IMySQL; Подключаемые файлы брал здесь: http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1318 авторMySQL.Query - Это что такое? SQL-запрос к базе данных ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 16:11:17 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
Имхо, у вас большая часть времени бессмысленно теряется в OFFSET-ах. И, кстати, LIMIT без ORDER BY - рулетка. Рискуете некоторые записи два раза обработать, а некоторые ни разу. Я бы сделал так: Цикл по запросу вида Код: sql 1. до Eof. В цикле запросы: Код: sql 1. Код: sql 1. Обязательно должен быть индекс из полей CODE, NUM. В данном случае порядок полей в индексе не важен. Для других задач может быть важен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 16:20:43 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
useronforumавторЭто Delphi? Delphi, но вопрос по правильности SQL-запросов на изменение BLOB-поля текущей записи. var MySQL: IMySQL; Подключаемые файлы брал здесь: http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1318 авторMySQL.Query - Это что такое? SQL-запрос к базе данных тогда я ваще не понимаю. если вопрос имено про склель строку, и метод апдейт назван нахудой конец (исхожу из слов, не знаю как обновить поэтому приходиться так).... то похоже я тоже не умею в базе строчку обновить. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 16:24:38 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
а вообще, здаёться мне лучше будет так 1)код который выгрузит нам нужные блоб поля в файлы на шдд 2)код на делфи обрабатывает эти файлы, и чтото там меняет сохраняя 3)потом идёт серия апдейтов указывая вкачестве значения поля LOAD FILE fname если действительно хочеться оптимизировать... то надо избежать конвертаций бинарных данных в строку и обратно, как на стороне мускла так и на стороне клиента. под словом файл, имееться ввиду любая ересь, с которой сможет работать мускл по типу SELECT INTO FILE LOAD FROM FILE но скорей всего это будет действительно физический файл на шдд. обход записей в базе для обработки, обычно делаеться либо курсором либо по типу описано выше. ибо не будете же вы ни молиться чтоб никто в базу ничего не вставил /не удалил ни блокировать всю базу на время этой обработки любые селекты что вы изобретаете, не дадут ожидаемый результат если появяться новые записи, или удаляться старые. либо курсор, либо снимок базы но не надеяться на богов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 16:32:15 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
alex5646574987654531)код который выгрузит нам нужные блоб поля в файлы на шдд 2)код на делфи обрабатывает эти файлы, и чтото там меняет сохраняяЗачем промежуточное сохранение в файл? это же утроение физического ввода-вывода. Раз уж прочитали из MySQL BLOB в память, то в памяти его и обрабатывать. alex564657498765453если действительно хочеться оптимизировать... то надо избежать конвертаций бинарных данных в строку и обратно, как на стороне мускла так и на стороне клиента.Вроде бы BLOB-ы такой конвертацией не страдают... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 16:35:59 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
miksoft, серьёзно ??? а зачем мы при соединении указываем кодовую страницу??? не потому ли что общение исключительно текстом! база из бинарника делает 100ef67a7c7b мы врядли обрабатывая блоб, обрабатываем его имено в ввиде такой строки. идёт обратное преобразование в цепочку байт цепочку байт обрабатываем, формируем ТЕКС СКЛ ! обратно конвертация, кидаем в базу, там обратная конвертация. про файлы, я не говорю что файлы быстрее, я говорю что ему один чорт надо все сначало выгрузить, обрабатывать, потом загружать назад, а не надеяться на чесное пионерское, что за эти 10 часов никто не поменяет число записей в таблице(вставка, удаление) и раз уж их все всторону смещать, я бы делал имено в файлы. хотя ... он сказал 10000 записей и 3гектара база, значит один блоб гдето 300кб... мдя...файлы плохая затея. ЗЫ а вообще меня смущает постановка вопроса... blob тип это как бы не для того чтоб брать и 10 байт в нём менять. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 16:46:57 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
alex564657498765453а зачем мы при соединении указываем кодовую страницу???Для строковых полей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 16:48:43 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
miksoft, так же нужно отметить, что если мы его прочитали в память, и из памяти толкнули в мускл, далеко не тоже самое , что мы один раз прочитали с шдд цепочку байт, и один раз записали. мы же про блоб говорим, тоесть я могу гиг в базу кидануть вкачестве блоба, врядли сеть быстро передаст гиг,и врядли оно будет лежать всё в оперативке, скорей всего в своп повалиться... ЗЫ не зря же много когда используеться имено временный файл - это тогда, когда обьёмы не малые(не 2,4,8,16 байт) - когда есть шанс бросания в своп и обратно, а это куда медленее чем самому красивенько кидать в файл, потом считывать) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 16:52:00 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
miksoftalex564657498765453а зачем мы при соединении указываем кодовую страницу???Для строковых полей. :) ней, для текста общения... просто латиница, на которой язык скл во всех кодовых страницах одинакова, и поэтому всегда читаеться, а не читаються только текстовые поля. пойми мне правильно, сказать что мы указываем кодировку только для текстовых полей, тоже самое что мы указываем в штмл кодировку только для - содержания тегов, значений текстовых переменых. согласен фиг доколупаешься, ибо действительно только они будут не верно интерпретированы. но всётаки щитаю что кодировка указываеться для протокола, который основан на передаче текста! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 16:55:58 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
alex564657498765453скорей всего в своп повалиться...откуда эти фантазии про своп, если там средний размер блоба 300Кбайт ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 17:04:07 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
оптимизировать можно исключив limit и выбирать по одной записи, лимит может вносить существенное торможение даже при увеличении обращений к серверу это сэкономит время чтои советует miksoft ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 17:13:40 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
авторЯ бы сделал так: Цикл по запросу вида 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 17:23:28 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
авторВ цикле запросы: SELECT IMAGE FROM MyTable WHERE CODE=... AND NUM=... UPDATE MyTable SET MyTable.IMAGE=... WHERE CODE=... AND NUM=... Не понимаю зачем первая строка, ведь вторая строка не использует результат первой? Или это один запрос? гыыыы первая выбирает данное второе записывает изменённое данное CODE=... AND NUM=... - фильтрация данных для выбора и для записи limit забирает всё время ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 17:40:28 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
авторавтор Я бы сделал так: Цикл по запросу вида 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 запись? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 17:50:21 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
И есть ли в SQL команда на изменение i-ой записи в таблице без "WHERE"? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 17:53:05 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
И в какой момент данные передаются в программу: автор query_result := MySQL.Query('SELECT * FROM MyTable LIMIT 10 OFFSET ' + IntToStr(offset1)); или авторquery_result.FetchRow ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 18:00:23 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
useronforum, хм...если тебя устроит перенести логику на мускл, так напиши хранимку которая сделает нужные замены с блобами... всётаки раскажи, что за замены ты с блобом делаешь, что надо их хранить в базе а не в файлах на шдд, и что нужны такие замены.... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 18:04:12 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
Базу данных не я проектировал. Структуру базы данных изменять нельзя и другие изменения мне вносить нельзя. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 18:10:23 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
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=... Не понимаю зачем первая строка, ведь вторая строка не использует результат первой? Или это один запрос?Нет, это два запроса. Первый читает блоб, потом ваша обработка, второй сохраняет блоб. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 18:14:18 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
авторДействительно SELECT "CODE, NUM" выдаст записи без поля BLOB. расшифруй ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 18:15:46 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
Про ключи узнал: PRIMARY KEY (`CODE`,`NUM`,`DATE1`). авторНе знаю как у используемого компонента, а у нормальных Query можно ограничить размер потребляемой памяти буфером хоть на одну запись. Так что лимит сам по себе не нужен. Программа начинала занимать 900Мб и т.д. пока "Out of memory" не появилось. авторавторавтор Действительно SELECT "CODE, NUM" выдаст записи без поля BLOB. расшифруй IMAGE - BLOB-поле, которое занимает много байт. Если его в SELECT не ставить, то меньше информации передаётся SELECT. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 18:26:44 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
useronforumПро ключи узнал: PRIMARY KEY (`CODE`,`NUM`,`DATE1`).О, это хорошо. Отдельный индекс создавать не надо. useronforumавторНе знаю как у используемого компонента, а у нормальных Query можно ограничить размер потребляемой памяти буфером хоть на одну запись. Так что лимит сам по себе не нужен. Программа начинала занимать 900Мб и т.д. пока "Out of memory" не появилось.Смотрите свойства компонента. Например, Unidirectional. Да и без этого, 10000 полей `CODE` и `NUM` займут копейки по сравнению с 900Мб. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 18:30:01 |
|
||
|
Быстрое попеременное чтение и изменение BLOB-записей таблицы в базе данных MySQL
|
|||
|---|---|---|---|
|
#18+
авторIMAGE - BLOB-поле, которое занимает много байт. Если его в SELECT не ставить, то меньше информации передаётся SELECT. а если ничего не ставить - ваще места буде дофига тебе ж разжевали Нет, это два запроса. Первый читает блоб, потом ваша обработка, второй сохраняет блоб. а если и при этом у тебя будет переполнение памяти - зачит при обработке блоба ты не правильно работаешь с памятью видимо в цикле создаются новые переменные, а не используются прежние ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2014, 18:53:45 |
|
||
|
|

start [/forum/topic.php?fid=47&fpage=180&tid=1834940]: |
0ms |
get settings: |
6ms |
get forum list: |
11ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
26ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
92ms |
get tp. blocked users: |
2ms |
| others: | 216ms |
| total: | 366ms |

| 0 / 0 |
