МySQL оптимизировать множество replace запросов

setevoi

Создатель
Регистрация
10 Апр 2013
Сообщения
43
Реакции
15
Есть обновление характеристик товара из эксель
Как оптимизировать
сейчас это более 3000 запросов и все растет в геометрической прогрессии :D

Код:
replace into goods_chars set content='Да',goods_id=110, char_id=434
replace into goods_chars set content='Нет',goods_id=110, char_id=436
replace into goods_chars set content='Иногда',goods_id=110, char_id=439
replace into goods_chars set content='Есть',goods_id=110, char_id=474
replace into goods_chars set content='Бывает',goods_id=110, char_id=484


replace into goods_chars set content='нет',goods_id=120, char_id=586
replace into goods_chars set content='Wi-fi',goods_id=120, char_id=589
replace into goods_chars set content='есть',goods_id=120, char_id=590
replace into goods_chars set content='Есть',goods_id=120, char_id=591
replace into goods_chars set content='есть',goods_id=120, char_id=594
 
Выглядит как хранилище ключ-значение.
тут либо в транзакции обернуть, либо аяксом отправлять на правку каждое поле отдельно
 
Выглядит как хранилище ключ-значение.
тут либо в транзакции обернуть, либо аяксом отправлять на правку каждое поле отдельно

в транзакции это как ?

структура у таблиц под характеристики такая

Код:
CREATE TABLE IF NOT EXISTS `goods_chars` (
  `char_id` int(10) unsigned DEFAULT NULL,
  `goods_id` int(10) unsigned DEFAULT NULL,
  `content` varchar(255) DEFAULT NULL,
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`),
  UNIQUE KEY `char_id` (`char_id`,`goods_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=166084 ;


CREATE TABLE IF NOT EXISTS `gt_chars` (
  `name` varchar(255) NOT NULL DEFAULT '',
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=473
 
Последнее редактирование:
в транзакции это как ?
Для просмотра ссылки Войди или Зарегистрируйся
Для просмотра ссылки Войди или Зарегистрируйся
Для просмотра ссылки Войди или Зарегистрируйся


Пример:
PHP:
mysql_query("START TRANSACTION");
mysql_query("replace into goods_chars set content='нет',goods_id=120, char_id=586");
mysql_query("replace into goods_chars set content='Wi-fi',goods_id=120, char_id=589");
mysql_query("replace into goods_chars set content='есть',goods_id=120, char_id=590");

// тут проверяем прошел ли replace нормально
if ($a1 && $a2 && $a3) {
    mysql_query("COMMIT");
} else {      
    mysql_query("ROLLBACK");
}
 
с транзакциями понял, но не уверен что это правильное решение
думаю в сторону
UPDATE goods_chars A JOIN gt_chars B
чтобы избавиться от ключа char_id

Чтение мануала привело к такому решению )
UPDATE нескольких строк за раз

Код:
insert into goods_chars (`char_id`,  `goods_id` ,  `content` ) 
values(39,1,'Да'),(40,1,'Нет')
on duplicate key update val =values(content);
 
Последнее редактирование модератором:
Чтобы быстро работало, можно сделать так: Данные составить таким образом, чтобы они одним запросом (или несколькими, по 2000строк за раз) добавлялись в специально созданную таблицу
Потом эти данные можно легко добавить с помощью хранимой процедуры, например.
 
Если не ошибаюсь, с ON DUPLICATE KEY UPDATE крутится счетчик для primary key.

ИМХО стоит его использовать там, где немного запросов
 
Транзакция, как пишет ArtyGrand, только вначале ALTER TABLE `...` ENGINE=InnoDB так как транзакции поддерживают далеко не все типы подсистем хранения. И только REPLACE INTO ..., так как ODKU Для просмотра ссылки Войди или Зарегистрируйся. По производительности - увеличить "key_buffer_size" до максимума, чтобы быстрее работать с индексами, уменьшить "max_heap_table_size" до 128MB, увеличить "tmp_table_size" - чем больше тем лучше
 
а что если тебе использовать синтаксис для массовой вставки, вместо 3000 запросов используй 1 строку с кучей values
Код:
REPLACE INTO goods_chars (content,goods_id,char_id)
        VALUES ('Да',110,434),('Нет',110,436)...
протести и как следующий вариант - можно попробовать исп. временную таблицу, а функцию replace сделать вручную через insert+delete но уже с таблицей
 
Назад
Сверху