SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 07.08.2011 20:09:00

vasya38
Участник
Зарегистрирован: 07.08.2011
Сообщений: 3

оптимизация UPDATE

Имеем таблицу в БД:

CREATE TABLE IF NOT EXISTS `data` (
  `id` mediumint(8) unsigned NOT NULL auto_increment,
  `userid` smallint(5) unsigned NOT NULL default '1',
  `data` varchar(40) NOT NULL,
  `type` set('type1','type2','type3','type4','type5','type6') NOT NULL default 'type1',
  `date` timestamp NOT NULL default CURRENT_TIMESTAMP,
  `status` tinyint(1) unsigned NOT NULL default '0',
  `history` varchar(100) NOT NULL default '',
  PRIMARY KEY  (`id`),
  KEY `type` (`type`,`status`),
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

К БД подключается приложение, которое делает выборку данных `data`, их обрабатывает и обновляет записи для каждой строки `data`:

UPDATE `data` SET `history` = 'sometext' WHERE `type` LIKE 'type1' AND `status` LIKE '0' AND `data` LIKE '14573cbe576d868b04da57fb9d749458' AND `history` LIKE '...';

Данные обновляются транзакциями пачками по 500 запросов (SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED). Объем данных подвергаемых обработке - от десятков до нескольких десятков тысяч записей.

Проблема в том, что подобные запросы выполняются крайне медленно, по логам MySQL - 5-6 запросов в секунду для таблицы `data` размером в несколько тысяч записей. Для таблицы в 20 тыс. записей скорость падает до 3-х запросов в секунду. Пробовал ввести дополнительный полнотекстовый индекс для полей `data` и `history` (FULLTEXT KEY `data` (`data`,`history`) - скорость не увеличилась. Пробовал изменить тип таблицы на InnoDB - скорость упала до 2-х запросов в секунду. Для того чтобы исключить влияние стороннего приложения - выполянл запросы непосредственно на сервере - получаются примерно те же временные промежутки.

Подскажите, каким образом можно поднять скорость обновления данных?

Неактивен

 

#2 07.08.2011 22:32:45

evgeny
Гуру
Зарегистрирован: 04.05.2009
Сообщений: 335

Re: оптимизация UPDATE

Для начала убедитесь что условие запроса работает оптимально.

EXPLAIN SELECT * FROM `data`  WHERE `type` LIKE 'type1' AND `status` LIKE '0' AND `data` LIKE '14573cbe576d868b04da57fb9d749458' AND `history` LIKE '...';

SELECT COUNT(*) FROM `data`  WHERE `type` LIKE 'type1';
SELECT COUNT(*) FROM `data`  WHERE `status` LIKE '0';
SELECT COUNT(*) FROM `data`  WHERE `data` LIKE '14573cbe576d868b04da57fb9d749458';
SELECT COUNT(*) FROM `data`  WHERE `history` LIKE '...';
 

Неактивен

 

#3 08.08.2011 07:26:10

vasya38
Участник
Зарегистрирован: 07.08.2011
Сообщений: 3

Re: оптимизация UPDATE

Спасибо за ответ. Действительно, в моем случае индексы были настроены не оптимально:

EXPLAIN SELECT * FROM `data`  WHERE `type` LIKE 'type1' AND `status` LIKE '0' AND `data` LIKE '14573cbe576d868b04da57fb9d749458' AND `history` LIKE '...';

id     select_type     table     type     possible_keys     key     key_len     ref     rows     Extra
1     SIMPLE         data     ALL     type         NULL     NULL         NULL     121017     Using where

Переделал индекс следующим образом: KEY `data` (`data`), в итоге получаем:
id     select_type     table     type     possible_keys     key     key_len     ref     rows     Extra
1     SIMPLE         data     range     data         data     122         NULL     4     Using where

Если задать три разных индекса KEY `data` (`data`), KEY `type` (`type`), KEY `status` (`status`):
id     select_type     table     type     possible_keys         key     key_len     ref     rows     Extra
1     SIMPLE         data     range     data,type,status     data     122         NULL     4     Using where

По логу mysql.log и в первом, и во втором случае скорость выполнения UPDATE'ов увеличилась до 13 в секунду (т.е. 0,07 на один запрос). Однако если выполнять единичный UPDATE через phpMyAdmin время составляет около 0,0013 сек.

Почему такая разница во времени выполнения получается, может причина в использовании транзакций?

Неактивен

 

#4 08.08.2011 16:09:35

evgeny
Гуру
Зарегистрирован: 04.05.2009
Сообщений: 335

Re: оптимизация UPDATE

Переводим на InnoDB

В my.cnf пишем

[mysqld]
innodb_flush_logs_at_trx_commit=0

Если захочется более высокой производительности то можно ещё подкрутить некоторые параметры в my.cnf , это уже подскажут paulus ,rgbeast

Неактивен

 

#5 08.08.2011 20:35:32

vasya38
Участник
Зарегистрирован: 07.08.2011
Сообщений: 3

Re: оптимизация UPDATE

Мои эксперименты уже с новыми индексами показали, что в моём случае скорость выполнения UPDATE не зависит от типа таблицы (MyISAM или InnoDB). Поставил базу на локальной машине - скорость возросла и составила порядка 0,0015 сек на запрос. Отсюда делаю вывод, что корень проблемы кроется в низкой скорости Интернет-соединения для случая работы приложения с удалённой базой. Поэтому спасибо за ответы, тему можно считать закрытой.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson