Задавайте вопросы, мы ответим
Вы не зашли.
Имеем таблицу в БД:
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-х запросов в секунду. Для того чтобы исключить влияние стороннего приложения - выполянл запросы непосредственно на сервере - получаются примерно те же временные промежутки.
Подскажите, каким образом можно поднять скорость обновления данных?
Неактивен
Для начала убедитесь что условие запроса работает оптимально.
Неактивен
Спасибо за ответ. Действительно, в моем случае индексы были настроены не оптимально:
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 сек.
Почему такая разница во времени выполнения получается, может причина в использовании транзакций?
Неактивен
Переводим на InnoDB
В my.cnf пишем
[mysqld]
innodb_flush_logs_at_trx_commit=0
Если захочется более высокой производительности то можно ещё подкрутить некоторые параметры в my.cnf , это уже подскажут paulus ,rgbeast
Неактивен
Мои эксперименты уже с новыми индексами показали, что в моём случае скорость выполнения UPDATE не зависит от типа таблицы (MyISAM или InnoDB). Поставил базу на локальной машине - скорость возросла и составила порядка 0,0015 сек на запрос. Отсюда делаю вывод, что корень проблемы кроется в низкой скорости Интернет-соединения для случая работы приложения с удалённой базой. Поэтому спасибо за ответы, тему можно считать закрытой.
Неактивен