Покинул форум
Сообщений всего: 1033
Дата рег-ции: Май 2012
Помог: 30 раз(а)
На данный момент есть задача, сгенерировать некий список эллементов и сохранить его где-то. Каждый эллемент в принципе это строка длинною от 2 до 10 символов, и все) Данный список насчитывает примерно 80 миллионов записей (для начала). По глупости для начала выбрал MySQL. Скрипт уже работает без остановки пару суток и сгенерировал всего 22млн записей. Запрос на count(*) выполняется чертовски долго. В общем mySQL в данном случае не думаю что будет еще шевелиться когда сгенерируются все 80млн записей и я начну эти записи обрабатывать) Посоветуйте, что будет хорошо справляться с большим количеством необъемных строк? Есть мысли попробовать redis... (Добавление)
P.S. на чистом php, без БД у меня список в 80млн строк сгенерировался за 3 минуты. Запустил этот же скрипт но все строки сохраняются в БД и он 22млн вставляет уже пару суток))
caballero
Отправлено: 03 Октября, 2014 - 21:04:31
Активный участник
Покинул форум
Сообщений всего: 5998
Дата рег-ции: Сент. 2011 Откуда: Харьков
Покинул форум
Сообщений всего: 378
Дата рег-ции: Сент. 2014
Помог: 10 раз(а)
[+]
Зависит от того, как вы собираетесь обрабатывать.
Если это все нужно для ваших внутренних целей, работа с данными последовательна и нет множества конкурентных запросов, то попробуйте MyISAM тип таблицы. Там быстрый INSERT и COUNT(*) работает быстро. Это будет лучше, чем пробовать другие типы СУБД. Если вам нужны индексы на элементы, то добавьте их уже после заполнения таблицы - это будет в общей сложности быстрее. (Добавление)
В коде где у вас INSERT - используйте prepare (один раз prepare и потом много раз execute с новыми данными) - этим уменьшите приличный оверхед синтаксического анализа в MySQL.
----- self-banned
RickMan
Отправлено: 03 Октября, 2014 - 21:15:55
Участник
Покинул форум
Сообщений всего: 1033
Дата рег-ции: Май 2012
Помог: 30 раз(а)
caballero да, как только написал пост, осознал это и исправил. Теперь идет намного быстрее но всеже скорости далеко не те что хотелось бы видеть. Только вот в моем случае надо использовать MyISAM при генерации данных и InnoDB уже при обработке..
MiksIr спасибо, щас попробую.
MiksIr
Отправлено: 03 Октября, 2014 - 21:20:37
Забанен
Покинул форум
Сообщений всего: 378
Дата рег-ции: Сент. 2014
Помог: 10 раз(а)
[+]
Я полагаю, что генерировать в MyISAM, а потом ALTER-нуть таблицу в InnoDB будет быстрее, чем лить в InnoDB напрямую, но это ИМХО, не проверял ;)
Но если нужно лить в InnoDB... ну хотя бы с этим http://dev[dot]mysql[dot]com/doc/refman/[dot][dot][dot]og_at_trx_commit поиграйтесь, иначе у вас после каждого инсерта идет синк на диск, что в общем очень медленно =)
Покинул форум
Сообщений всего: 1033
Дата рег-ции: Май 2012
Помог: 30 раз(а)
MiksIr не, лью та я щас в MyISAM. Потом уже подумаю как делать) НО скорость поменялась существенно... При таких обьемах я как-то недооценил важность типа)
caballero
Отправлено: 03 Октября, 2014 - 22:07:46
Активный участник
Покинул форум
Сообщений всего: 5998
Дата рег-ции: Сент. 2011 Откуда: Харьков
Помог: 126 раз(а)
insert быстрее в innodb выполняется.
а вот выбирать уже быстрее с isam (Добавление)
ну и индексы отключить на время вставки (Добавление)
еще можно множественную вставку - одним инсертом несколько десятков строк - на времени трафика сэкономится
Покинул форум
Сообщений всего: 1033
Дата рег-ции: Май 2012
Помог: 30 раз(а)
caballero не соглашусь. В моем случае с таблицей работает 1 запущенный скрипт, тоесть блокировка таблицы мне не страшна. Транзакции и внешние ключи мне тут не нужны. Так же в моем случае MyISAM дает наилучший прирост из этих двух типов... Да и на практике поверьте прирост нехилый... (Добавление)
С момента написания поста, и смены типа, количество записей выросло с 20млн до 60млн) думаю тут прирост скорости неимеверен)
MiksIr
Отправлено: 03 Октября, 2014 - 23:00:14
Забанен
Покинул форум
Сообщений всего: 378
Дата рег-ции: Сент. 2014
Помог: 10 раз(а)
[+]
caballero пишет:
insert быстрее в innodb выполняется
_Запись_ в MyISAM быстрее. Хотя бы просто потому, что в InnoDB нужно не просто записать данные, но еще записать в лог, да еще сбросить все это принудительно на диск. В MyISAM - просто записать данные, и сброса на диск принудительного там нет.
Другое дело, что MyISAM для обеспечения корректной записи блокирует всю таблицу. При большом числе конкурентных операций они мешают друг другу блокировками таблицы. InnoDB решает эту проблему и вполне может быть быстрее.
Когда же человек пишет из одного скрипта потоком данные - MyISAM будет быстрее (в силу своей простоты).
caballero пишет:
а вот выбирать уже быстрее с isam
Весьма спорное утверждение. Очень много кейсов, когда innodb быстрее. Зависит от типа запросов, конкуренции, количества ядер сервера, состояния кеша.
Например, выборка по PK - InnoDb быстрее уже давно из-за кластерного индекса.
В InnoDB решены многие узкие места MyISAM, особо принципиальные при большой конкуренции и гораздо более эффективно сделано управление кешом.
----- self-banned
caballero
Отправлено: 03 Октября, 2014 - 23:26:22
Активный участник
Покинул форум
Сообщений всего: 5998
Дата рег-ции: Сент. 2011 Откуда: Харьков
Помог: 126 раз(а)
Цитата:
Хотя бы просто потому, что в InnoDB нужно не просто записать данные, но еще записать в лог, да еще сбросить все это принудительно на диск.
запускать с транзакцией никто не заставляет
Цитата:
Например, выборка по PK - InnoDb быстрее уже давно из-за кластерного индекса.
это если выборка по этому индексу. Не говоря уже сколько времени уйдет на его построение
При использовании таблиц, поддерживающих транзакции (таких как InnoDB, BDB), в MySQL можно отключить режим autocommit при помощи следующей команды:
SET AUTOCOMMIT=0
После этого необходимо применить команду COMMIT для записи изменений на диск или команду ROLLBACK, которая позволяет игнорировать изменения, произведенные с начала данной транзакции.
MiksIr
Отправлено: 06 Октября, 2014 - 11:35:10
Забанен
Покинул форум
Сообщений всего: 378
Дата рег-ции: Сент. 2014
Помог: 10 раз(а)
[+]
Это отключает автоматический коммит транзакций, но не отключает старт транзакции.
----- self-banned
Dastor
Отправлено: 07 Октября, 2014 - 12:33:05
Гость
Покинул форум
Сообщений всего: 66
Дата рег-ции: Окт. 2014
Помог: 3 раз(а)
Я бы решил эту задачу так:
Сгенерировал файл в csv-формате с нужными данными системными средствами (shell к примеру).
В мускул бы залил этот файл с помощью load data local infile из командной строки (или из php):
К примеру можно создать файл loader.sql с таким содержимым
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.