@stainer

Как обработать и сравнить большой массив данных?

Добрый день!
Впервые столкнулся в работе с большим объемом данных, поэтому стандартные решения не подходят.
Дано: Многомерный массив
[0] -> 
[0][0] -> Артикул
[0][1] -> Цена
[0][2] -> Название

[1] ->
[1][0] -> .....
[1][1] -> .....
[1][2] -> .....
И так далее..

Далее: в базе Mysql хранятся товары, табличка со столбцами:
id,name,article,price (айди, название, артикул, цена)

Суть задачи в том, чтобы из массива обновлять цены в бд, если в массиве она отличается от значение в таблице.

Но если пройтись foreach по массиву и на каждой итерации сравнивать значение со значением в бд, после чего обновлять (а это по 2 запроса на каждой итерации), то скрипт наглухо кладет сервер минут на 10.

Вопрос: как обновить цены в бд из массива, при это максимально сократить нагрузку и время выполнения?
  • Вопрос задан
  • 222 просмотра
Пригласить эксперта
Ответы на вопрос 2
erge
@erge
Примус починяю
вариантов есть несколько....
1) загружаете данные доступными вам способами во временную таблицу, далее UPDATE по этой таблице
если из PHP, то собрать из массива запрос вида
INSERT INTO tmp_goods (name, article, price)
  VALUES ('NAME_1', 'ARTICLE_1', PRICE 1),
.......
         ('NAME_N', 'ARTICLE_N', PRICE_N)
;


после чего выполнить UPDATE:
UPDATE goods g
  INNER JOIN tmp_goods t ON t.article = g.article
  SET g.price = t.price
  WHERE g.price != t.price
;


и очистить tmp_goods если она более не нужна.

2) собрать из массива запрос вида:
UPDATE goods
SET price = CASE article
WHEN ARTICLE_1 THEN PRICE_1
WHEN ARTICLE_2 THEN PRICE_2
....
ELSE price END


так же есть операторы:
REPLACE ,
INSERT ON DUPLICATE KEY UPDATE
и вообще погуглите - MySQL множественный апдейт

и... еще вариант:
можно обойтись без временной таблицы (как в варианте 1)...
соберите из массива запрос вида:

UPDATE goods g
  INNER JOIN (
    SELECT 'ARTICLE-1' AS article, PRICE_1 AS price UNION
    SELECT 'ARTICLE-2', PRICE_2 UNION
    SELECT 'ARTICLE-3', PRICE_3 UNION
...
    SELECT 'ARTICLE-N', PRICE_N
    ) t ON t.article = g.article
  SET g.price = t.price
  WHERE g.price != t.price
;


смотрите пример на sqlfiddle (сосбтвенно update в левом поле описания схемы)
Ответ написан
Комментировать
usdglander
@usdglander Куратор тега PHP
Yipee-ki-yay
то скрипт наглухо кладет сервер минут на 10

Вряд ли он прям наглухо кладёт. Обычная обработка. Да долго, но очень часто подобные задачи возникают, ничего страшного там нет. Пусть работает.

Можно сократить количество запросов за счёт того, что SELECT для проверки не нужен, например.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы