Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Импорт и обработка большого файла CSV

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Без описания
dmaw
Отправлено: 24 Июля, 2016 - 18:53:39
Post Id



Частый гость


Покинул форум
Сообщений всего: 227
Дата рег-ции: Сент. 2009  
Откуда: Беларусь, Витебск


Помог: 0 раз(а)




Добрый день!

Есть Интернет-магазин и поставщик с CSV-прайсом на 20 000 строк/товаров.
Мне нужно чтобы скрипт с помощью крона ежедневно обновлял цены из CSV.
Делаю я это так: скачиваю новый CSV, читаю файл построчно, ищу совпадения по артикулу, если товар есть обновляю его цену и наличие, если товар не найден, то создаю его.
Проблема в том, что скрипт перестаёт работать после 10 000 строк.

Вопрос: можно ли как-то давать скрипту "передышку" или как-то разбивать процесс на мелкие, чтобы скрипт успевал обработать все 20 000 строк?

Часть кода:
PHP:
скопировать код в буфер обмена
  1. //читаю весь файл в массив
  2. $arr = array();
  3. $file = fopen('price.csv', 'r');
  4. while(!feof($file))
  5. {
  6.      $arr[] = fgetcsv($file, 0, ";");
  7. }
  8. fclose($file);
  9.  
  10. foreach($arr as $row) // Цикл по строкам
  11. {
  12. // тут начинаются проверки на существование товаров и обновление цен.
  13.  

(Отредактировано автором: 24 Июля, 2016 - 18:54:48)

 
 Top
Мелкий Супермодератор
Отправлено: 24 Июля, 2016 - 19:53:51
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




create temporary table
load data infile
create index on temporary table, если нужно для мерджа
begin
multitable update, insert .. select, delete если нужен
commit
drop temporary table
Чистый sql, всосать и помержить можно огромный массив данных.


-----
PostgreSQL DBA
 
 Top
Fart
Отправлено: 25 Июля, 2016 - 06:50:43
Post Id



Посетитель


Покинул форум
Сообщений всего: 324
Дата рег-ции: Июль 2016  


Помог: 10 раз(а)




ты даже поленился зайти по ссылке csv на сайте. проверяешь конец файла зачем? тебе первоначально нужно прогнать по-бырому счетчик, а ты феофиш как старушка с клюшкой на лестничной площадке!!! попробуй примеры сначала использовать. как код оптимизируешь звони !!!

у базы данных записей может быть и миллион, а с корявым кодом и БД даст такой отклик, что проще не заниматься программированием вовсе!!!!

(Отредактировано автором: 25 Июля, 2016 - 06:52:40)

 
 Top
dmaw
Отправлено: 25 Июля, 2016 - 12:55:57
Post Id



Частый гость


Покинул форум
Сообщений всего: 227
Дата рег-ции: Сент. 2009  
Откуда: Беларусь, Витебск


Помог: 0 раз(а)




Fart пишет:
ты даже поленился зайти по ссылке csv на сайте. проверяешь конец файла зачем? тебе первоначально нужно прогнать по-бырому счетчик, а ты феофиш как старушка с клюшкой на лестничной площадке!!!

Проверил оба варианта на скорость выполнения:
PHP:
скопировать код в буфер обмена
  1. while(!feof($file)) // 2.3 сек
  2. while(($data = fgetcsv($file, 0, ";")) !== FALSE) // 2.5 ... 3 сек

Старушка оказалась ни при чём Улыбка
 
 Top
Fart
Отправлено: 27 Июля, 2016 - 18:41:54
Post Id



Посетитель


Покинул форум
Сообщений всего: 324
Дата рег-ции: Июль 2016  


Помог: 10 раз(а)




1. проверить память
2. отказаться от работы с fgetcsv и ИМХО ручками обрабатывать файл. с fgets работает в х10-х20 раз быстрее
3. проверить сам файл, возможны ошибки и цсв сам по себе очень баговый формат.

PS да и вообще, приятнее работать с json

(Отредактировано автором: 27 Июля, 2016 - 18:55:05)

 
 Top
dmaw
Отправлено: 27 Июля, 2016 - 19:11:39
Post Id



Частый гость


Покинул форум
Сообщений всего: 227
Дата рег-ции: Сент. 2009  
Откуда: Беларусь, Витебск


Помог: 0 раз(а)




Fart пишет:
1. проверить память
2. отказаться от работы с fgetcsv и ИМХО ручками обрабатывать файл. с fgets работает в х10-х20 раз быстрее
3. проверить сам файл, возможны ошибки и цсв сам по себе очень баговый формат.

PS да и вообще, приятнее работать с json

fgets проверил на скорость, раза в два быстрее данные получает, этого всё равно будет мало.
ЦСВ без ошибок, просто очень большой Улыбка
json я бы и сам рад, но поставщикам не прикажешь, есть такие кто екселем отдаёт Улыбка
Fart, спасибо!
(Добавление)
Суть даже не в скорости чтения через fgetcsv, там 2-3 секунды, а в том, что я в цикле потом запросы делаю, т.е. фактически получается сколько строк столько и запросов, поэтому получается фигня. Самый правильный ответ дал Мелкий, только надо догнать как всё это построить.
 
 Top
Fart
Отправлено: 27 Июля, 2016 - 21:29:02
Post Id



Посетитель


Покинул форум
Сообщений всего: 324
Дата рег-ции: Июль 2016  


Помог: 10 раз(а)




у меня за 2.0 сек обрабатывает цсв файл объемов 50-60мб.

если скинешь файл, то можно будет сказать, что сделать, но мои мысли о том, что память не дает возможность обрабатывать файл с байтами выше, чем не сервере.

по поводу скорости: лучше на php7 переходить с норм хостом... а с файлами работать начинает тяжело если объем большой и требуется более быстрого отклика.

по поводу СУБД... тут очевидно. с работой такого объема быстрее и проще...

PS либо переписать логику составления файлов цсв на мелкие с определенной категорией

(Отредактировано автором: 27 Июля, 2016 - 21:32:48)

 
 Top
dmaw
Отправлено: 27 Июля, 2016 - 22:58:25
Post Id



Частый гость


Покинул форум
Сообщений всего: 227
Дата рег-ции: Сент. 2009  
Откуда: Беларусь, Витебск


Помог: 0 раз(а)




Fart, спасибо, за помощь, попробую свои мысли реализовать.
По поводу php7 вопрос сложный, магазин официальный и находится в Беларуси, а у нас тут с одной стороны выбирать нет из чего, а с другой чудо законы, которые не позволяют размещать сайты за пределами страны.
 
 Top
dmaw
Отправлено: 30 Июля, 2016 - 23:10:06
Post Id



Частый гость


Покинул форум
Сообщений всего: 227
Дата рег-ции: Сент. 2009  
Откуда: Беларусь, Витебск


Помог: 0 раз(а)




Как упаковать 20 000 подобных запросов в один?

CODE (SQL):
скопировать код в буфер обмена
  1. UPDATE products SET price='8.04', WHERE artikul='456457' LIMIT 1 ;
  2. UPDATE products SET price='20.59', WHERE artikul='2346456465' LIMIT 1 ;
  3. UPDATE products SET price='2.16', WHERE artikul='345637457' LIMIT 1 ;
  4. UPDATE products SET price='6.67', WHERE artikul='34577457' LIMIT 1 ;
  5. UPDATE products SET price='165.31', WHERE artikul='75457' LIMIT 1 ;
  6. UPDATE products SET price='9.91', WHERE artikul='3463457457' LIMIT 1 ;
 
 Top
Fart
Отправлено: 31 Июля, 2016 - 10:48:47
Post Id



Посетитель


Покинул форум
Сообщений всего: 324
Дата рег-ции: Июль 2016  


Помог: 10 раз(а)




где то уже была тема про это. Вроде бы товарищ Мелкий приводил пример. в инете есть такой вариант:

UPDATE 'some_table'
SET
'field_1' = CASE 'id'
WHEN id_1 THEN data_1
WHEN id_2 THEN data_2
...
WHEN id_N THEN data_N
ELSE 'field_1' END,
'field_2' = CASE 'id'
WHEN id_1 THEN data_1
WHEN id_2 THEN data_2
...
WHEN id_N THEN data_N
ELSE 'field_2' END,

...

'field_N' = CASE 'id'
WHEN id_1 THEN data_1
WHEN id_2 THEN data_2
...
WHEN id_N THEN data_N
ELSE 'field_N' END
 
 Top
dmaw
Отправлено: 31 Июля, 2016 - 14:29:26
Post Id



Частый гость


Покинул форум
Сообщений всего: 227
Дата рег-ции: Сент. 2009  
Откуда: Беларусь, Витебск


Помог: 0 раз(а)




Что-то не догоняю как эту конструкцию правильно составить, нашел такой вариант:
CODE (SQL):
скопировать код в буфер обмена
  1. UPDATE mytable SET
  2.     fruit = CASE WHEN id=1 THEN 'orange' ELSE 'strawberry' END,
  3.     drink = CASE WHEN id=1 THEN 'water'  ELSE 'wine'       END,
  4.     food  = CASE WHEN id=1 THEN 'pizza'  ELSE 'fish'       END
  5. WHERE id IN (1,2);

т.е. как я понимаю на каждую ячейку будет куча условий в зависимости от строки. ELSE наверное мне не нужен.
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Вопросы новичков »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB