Модераторы: skyboy

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Настройки MySQL, большое количество insert'ов 
:(
    Опции темы
nIkTo
Дата 28.9.2010, 23:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 5.7.2007

Репутация: нет
Всего: нет



Подскажите настройки MySQL, и в обще буду благодарен любым советам как увеличить скорость выполнения вставок в таблицу.
Единственное улучшение которое использую это многострочная вставка.
PM   Вверх
sir_nuf_nuf
Дата 29.9.2010, 12:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 8
Всего: 31



Ну как бы стандартный вопрос - MyISAM vs InnoDB - что используете ?


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
nIkTo
Дата 29.9.2010, 14:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 5.7.2007

Репутация: нет
Всего: нет



Использую MyISAM
PM   Вверх
sir_nuf_nuf
Дата 29.9.2010, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 8
Всего: 31



попробуйте использовать insert delayed.


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
nIkTo
Дата 29.9.2010, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 5.7.2007

Репутация: нет
Всего: нет



sir_nuf_nuf, мне кажется это не решит проблемы, сейчас запросы собираются в очередь в программе, из за этого она сжирает всю память и умирает, если я правильно понял то insert delayed только переведёт эту очередь на сторону mysqld, то есть будет умирать mysql ...
Цитата

Обратите внимание: в настоящее время все записи, поставленные в очередь на добавление, хранятся только в памяти до тех пор, пока они не будут записаны на диск. Отсюда следует, что если выполнение mysqld будет завершено принудительно (kill -9) или программа умрет, то все находящиеся в очереди данные, которые не записаны на диск, будут потеряны!. 


Есть вариант увеличения работоспособности , но это затратно RAID 0+1

есть ещё идеи ?
PM   Вверх
Akina
Дата 29.9.2010, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 454



Цитата(nIkTo @  29.9.2010,  00:59 Найти цитируемый пост)
Единственное улучшение которое использую это многострочная вставка. 

Что Вы скрыли под термином "многострочная вставка"? пример плиз... скажем сборки трёх простеньких запросов (2 поля хватит).


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
nIkTo
Дата 29.9.2010, 19:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 5.7.2007

Репутация: нет
Всего: нет



Таблица :
Код

create table `rows` (
  `row_id` int not null auto_increment,
  `row_name` varchar(100) not null,
  `row_count` int not null,
  primary key (`row_id`),
  unique key (`row_name`)
) engine = MyISAM default character set = utf8 collate = utf8_bin;


В клиентской части (Perl скрипт) формируется очередь из данных на вставку, отдельный поток берёт из очереди данные и постепенно формирует запрос из 2000 записей, а потом отправляет на выполнение mysql ....

Код

insert ignore into `rows` values (null, 'data1', 10), (null, 'data2', 560), ....., (null, 'data2000', 100)



PM   Вверх
Akina
Дата 29.9.2010, 20:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 454



Кто Вас научил ТАК писать запросы??? 
1) Список полей следует перечислять ЯВНО.
2) Автоинкрементное ключевое поле в набор полей НЕ включается.
Код

insert ignore into `rows` (`row_name`,`row_count`) values ('data1', 10), ('data2', 560), ....., ('data2000', 100)


Добавлено через 2 минуты и 32 секунды
Кстати...  smile  ignore - это прелестно, но ошибки всё-таки надо обрабатывать. Или хотя бы ловить.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
nIkTo
Дата 29.9.2010, 20:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 5.7.2007

Репутация: нет
Всего: нет



Akina, прибавки в скорости это не дало никакой.
PM   Вверх
Akina
Дата 29.9.2010, 21:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 454



А я как бы и не ожидал...

Цитата(nIkTo @  29.9.2010,  17:12 Найти цитируемый пост)
если я правильно понял то insert delayed только переведёт эту очередь на сторону mysqld, то есть будет умирать mysql ...

А с чего ты решил, что он будет умирать? Он будет сливать записи в таблицу по мере возможности. Кстати, каково соотношение запросов запись/чтение в таблицу?
С дугой стороны - объясни, почему ты не хочешь сливать записи по мере их появления? зачем тебе непременно хочется набрать большую пачку? чем это оправдано?


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
nIkTo
Дата 29.9.2010, 21:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 5.7.2007

Репутация: нет
Всего: нет



Akina,

Цитата

А с чего ты решил, что он будет умирать?

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

Цитата

С дугой стороны - объясни, почему ты не хочешь сливать записи по мере их появления? зачем тебе непременно хочется набрать большую пачку? чем это оправдано? 


не думаю что 2000 запросов выполнится быстрее чем 1 но с большим количеством данных
PM   Вверх
Akina
Дата 29.9.2010, 23:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 454



Цитата(nIkTo @  29.9.2010,  22:42 Найти цитируемый пост)
не думаю что 2000 запросов выполнится быстрее чем 1 но с большим количеством данных 

На потолке подсмотрел? Может вполне быть, что 2000 запросов отработают быстрее. 
У тебя перл и мускул - на одной машине или на разных? если на разных - выделенный ли меж ними сегмент и какой пропускной способности? если на одной - то откуда берутся вообще эти 2000 записей? а дисковая подсистема на машине с мускулом - нормальная?

Цитата(nIkTo @  29.9.2010,  22:42 Найти цитируемый пост)
памяти на сервере всего 1gb

А какие задачи на сервере? сколько остаётся собственно серверу БД?


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
IgorIV
Дата 29.9.2010, 23:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 642
Регистрация: 7.9.2009

Репутация: нет
Всего: 8



nIkTo, конкретные цифры назови, сколько занимает вставка этих 2000 строк.
Как я понимаю, это вдс-сервер и при превышении лимита памяти убивается процесс с наибольшей памятью. Так?
PM MAIL   Вверх
sir_nuf_nuf
Дата 30.9.2010, 10:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 8
Всего: 31



nIkTo, заместо извращения со склейкой данных в одну пачку могу порекомендовать делать insert как prepared statement. 
Т.е. один раз подготовить statement а потом вставлять данные.




--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
nIkTo
Дата 30.9.2010, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 5.7.2007

Репутация: нет
Всего: нет



sir_nuf_nuf, если правильна вас понял, сделал так :
Код

my $insert = Thread::Queue->new;
....
threads->create(\&insert, $config)->detach;
....
sub insert {
  my $config = shift;
  my $mysql = DBI->connect("DBI:mysql:database=".$config->{basename}.";host=localhost", $config->{username}, $config->{password});
  my $statement = $mysql->prepare("insert delayed ignore into `rows` (`row_name`, `row_count`) values (?, ?)");
  while (my $values = $insert->dequeue) {
    $statement->execute($values->{row_name}, $values->{row_count});
  }
  $mysql->disconnect;
}


но опять же тут будет выполнятся 2000 запросов вместо 1.
Итог: через минуту в очереди $insert 122129 

PM   Вверх
sir_nuf_nuf
Дата 30.9.2010, 14:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 8
Всего: 31



nIkTo, Да, но очередь будет на стороне MySQL. 

И вообще, если у вас данные поступаю с такой частотой, что MySQL (на данной машине) не успевает их писать в таблицу - вас ничто не спасет от переполнения очереди.

Теперь техническая сторона вопроса: как сделать так что бы MySQL успевал ?
1) проверьте что это вообще возможно на вашей машине:
1.1) пишите в самую простую таблицу без доп. UNIQUE индексов, можно  вообще без индексов.
1.2) почитайте документацию и оптимизируйте буфера MyISAM
1.3) посмотрите (top, iostat, systat) во что упирается система при записи (по идее должна в диск)
1.4) Akina наверняка еще добавит что-то

Если все сделали и все равно очередь растет - у вас слабая машина. 

Кстати та часть скрипта которая пишет в очередь ($insert->enqueue) должна проверять ее наполнение и приостанавливаться если очередь полна.



--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
nIkTo
Дата 30.9.2010, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 5.7.2007

Репутация: нет
Всего: нет



Цитата

key buffer size    8,384,512


Это много или мало ?
PM   Вверх
Akina
Дата 30.9.2010, 16:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 454



8 мегабайт? при гектаре на сервере?
Сам-то как думаешь... кстати, по дефолту 16М


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
muzer
Дата 5.10.2010, 05:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

Репутация: 30
Всего: 31



1) Многострочная вставка - это правильно. Тут могу порекомендовать написать небольшой тест-скрипт, померить удельную скорость от изменения кол-ва данных в одной пачке именно ваших запросов, имеет смысл попробовать увеличить кол-во. В какой-то момент скорость перестанет расти.

Цитата(Akina @  30.9.2010,  00:14 Найти цитируемый пост)
На потолке подсмотрел? Может вполне быть, что 2000 запросов отработают быстрее. 

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

2) Основная проблема в ключе по varchar. Вы можете оптимизровать структуру таблицы, завести числовое поле равное какой-нибудь функции от row_name (например, crc32 (int) или половинке от md5 (bigint)), и уникальный ключ строить по ниму. Есть небольшая вероятность коллизий, но оно того стоит.

3) Есть такая фишка - delay_key_write. Если его включить, для данной таблицы или для всех, это в зависимости от значения key_buffer_size снизит вам нагрузку на диск при записи в таблицы. Есть минус - умирание mysql'я приведёт к порче индексов всех таблиц, для которых была включенна отложенная запись ключей. Но это решается myisamchck'ом перед стартом. Работает оно просто - пока есть свободный key_buffer - пишет ключи в момент выполнения запроса в память. Чтобы получить какой-то значимый эффект нужно увеличить key_buffer_size соразмерно кол-ву данных или возможностям хоста. Следить за наполнением буффера ключей можно через show global status like 'key_b%';
PM WWW   Вверх
Akina
Дата 5.10.2010, 09:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 454



Цитата(muzer @  5.10.2010,  06:49 Найти цитируемый пост)
Не может, увы. И не вижу причин упоминания потолка, даже если у вас нет практического опыта, представьте весь процесс вставки и посчитайте накладные расходы.

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


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
muzer
Дата 5.10.2010, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

Репутация: 30
Всего: 31



Цитата(Akina @  5.10.2010,  10:17 Найти цитируемый пост)
Простейший пример - неустойчивый канал связи с большим процентом потерь. 

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

Это сообщение отредактировал(а) muzer - 5.10.2010, 12:43
PM WWW   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




[ Время генерации скрипта: 0.0649 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.