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 :: Как сделать INSERT на 72 миллиона строк

 PHP.SU

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


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

> Описание: вопрос на собеседовании
Panoptik
Отправлено: 30 Марта, 2012 - 23:38:01
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2493
Дата рег-ции: Нояб. 2011  
Откуда: Одесса, Украина


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




вСЕМ доброго времени

вобщем сегодня вспомнил вопрос, который мне задавали на собеседовании при приеме на работу.
и так вопрос из сабжа: как вставить 72 миллиона записей в таблицу.

Не знаю в нужном ли форуме опубликовал тему. но вроде приближенно

так как я за пол года не сталкивался с такими задачками. может есть мысли у знающих
мысль 1:
проблемы:
длительное время выполнения. для выполнения нужно отключать максимальное время выполнения скрипта. А если дело обстоит на хостинге, запрещающем такие вещи?
мысль 2:
может есть способ написать хранимую процедуру или чтото типа того чтобы СУБД сама выполнила задание без помощи пхп.

формализуя задачу - значимость данных для этой задачи не предусмотрена, поэтому пусть есть таблица tbl: id - автоинкремент, data
нужно вставить данные в data числа от 1 до 72*10e6


и так, господа знатоки. есть решения?


-----
Just do it
 
 Top
altermann
Отправлено: 31 Марта, 2012 - 00:10:17
Post Id



Частый гость


Покинул форум
Сообщений всего: 196
Дата рег-ции: Март 2010  
Откуда: Днепропетровск


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




Поставить неограниченное время выполнения скрипта.
Добавить больше памяти для маневров.
Собирать многострочный инсерт с некоторым ограничением строк, допустим по 500 или более на сколько не жалко памяти.
Вставить в базу.
Почистить переменные.
Повторить.

Если кого-то осенило это делать через браузер, то нужно чтоб скрипт не прекращал работу если браузеру надоело ждать ответа ignore_user_abort = On.
Как обойти настройки хостера точно не знаю, можно попробовать расспараллеливание скрипта типа pcntl_fork.


-----
Я прирожденный кузнец, я не могу не куя!
 
 Top
Panoptik
Отправлено: 31 Марта, 2012 - 00:16:05
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2493
Дата рег-ции: Нояб. 2011  
Откуда: Одесса, Украина


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




а что вы подразумевали под "выделить побольше памяти" это на какие такие маневры? сформировать запрос, размером в 70Мб?)


-----
Just do it
 
 Top
DlTA
Отправлено: 31 Марта, 2012 - 00:28:47
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2952
Дата рег-ции: Окт. 2010  


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




можно воспользоваться дампером, они нынче даже из экселя(/csv) умеют данные читать

но честно говоря виртуальный хост от длительной нагрузки по любому падает, особенно если объем каждой записи неприлично большой. приходится делать с остановками (пока сервер баз данных сходит на переку))

но в любом случае процесс происходит за множественное количество обращений.

пробовал как то на локальных хост производить добавление в таблицу 10 000 записей путем чтения "ручками" данных из файла и выполнения запроса на добавление
по непонятным мне причинам навернулась база.
 
 Top
Panoptik
Отправлено: 31 Марта, 2012 - 00:33:29
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2493
Дата рег-ции: Нояб. 2011  
Откуда: Одесса, Украина


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




самое интересное что мне задали этот вопрос на собеседовании и я до сих пор не вижу нормального решения кроме как поставить безлимитное время выполнения скрипта
если речь идет о вставке через цикл на php


-----
Just do it
 
 Top
Okula
Отправлено: 31 Марта, 2012 - 01:08:26
Post Id



Участник


Покинул форум
Сообщений всего: 1389
Дата рег-ции: Окт. 2010  


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




Порциями выполнять запросы.
Если через хостинг - тек же порциями, но что бы не обременять пользователя обновлением скрипта выставить крон задание.
Если есть доступ SSH то тогда всё намного упрощается.
 
 Top
Panoptik
Отправлено: 31 Марта, 2012 - 01:14:42
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2493
Дата рег-ции: Нояб. 2011  
Откуда: Одесса, Украина


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




спасибо. вариант с кроном мне понравился. вроде как самый красивый


-----
Just do it
 
 Top
altermann
Отправлено: 31 Марта, 2012 - 10:19:38
Post Id



Частый гость


Покинул форум
Сообщений всего: 196
Дата рег-ции: Март 2010  
Откуда: Днепропетровск


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




Panoptik пишет:
а что вы подразумевали под "выделить побольше памяти" это на какие такие маневры? сформировать запрос, размером в 70Мб?)

Да, пусть не 70М, но и не по одной строке вставлять.

Panoptik пишет:
спасибо. вариант с кроном мне понравился. вроде как самый красивый

Я подозреваю что он единственный


-----
Я прирожденный кузнец, я не могу не куя!
 
 Top
EuGen Администратор
Отправлено: 31 Марта, 2012 - 11:16:20
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


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




Собеседование? Подозреваю, что имелось ввиду:
LOAD DATA INFILE
(это в любом случае наиболее быстрый способ)


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
roxoman
Отправлено: 20 Октября, 2015 - 21:57:17
Post Id


Новичок


Покинул форум
Сообщений всего: 9
Дата рег-ции: Окт. 2015  


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




Если еще интересно, то у меня задача была такая - заливать в базу гигантские прайс-листы, загружаемые пользователями на сервер в формате CSV. Единственное условие - неограниченное время выполнения скрипта (хотя можно это обойти - немного коряво, и скорость естественно будет ниже раз в 50, но при большом желании можно работать и с ограничением в 30 секунд - здесь нам поможет обработка кусками и AJAX).

Загружаем файл csv на сервер естественно, создаем еще один временный файл csv, затем начинаем читать загруженный файл функцией fgetcsv построчно - разбираем строку, оставляем то, что нужно, и записываем это дело в массив. Массив конечно растет с каждой итерацией, а выделять на эту процедуру несколько гигабайт памяти мы не можем, так как одновременно могут грузиться десятки прайс-листов разными людьми, а у нас VDS за 1000 руб. в месяц. Поэтому пользуемся функцией memory_get_usage - она поможет нам определить, что мы пододвигаемся к пределу выделяемой на скрипт памяти - как только пододвинулись сбрасываем данные из массива во временный CSV-файл, который мы создали вначале. Таким методом обходим весь загруженный файл.
После обхода у нас получился новый файл CSV с уже обработанными данными, готовыми к заливке в базу. И тут нам на помощь приходит LOAD DATA INFILE - это самый быстрый способ загрузить данные в базу.
В итоге у нас вот что: памяти хавает скрипт столько, сколько Вы укажите - хоть 12 Мб, скорость при этом отличная - прайс-лист с миллионом строк загружается в базу за пару минут (над данными еще множество сложных обработок производится по ходу разбора), причем при увеличении объема скорость растет именно в арифметической прогрессии, то есть 10 миллионов строк - будет 20 минут, а 72 миллиона - около 2-х часов (но опять-таки, если данные никак не обрабатывать, а просто заливать как есть, то возможно, и часа с головой хватит).

Если в чем-то не прав - поправьте, так как мне самому актуальна эта тема, потому что проект этот работает, и если есть варианты улучшить этот процесс, то готов выслушать.
Во всяком случае за полгода постоянной битвы над этой задачей я пришел именно к такому варианту.

Естественно это пример рабочей программы, а если Вам задавали конкретный вопрос "КАК?" и хотели услышать короткий ответ, то это, как писали выше, LOAD DATA INFILE - быстрее никак.

(Отредактировано автором: 20 Октября, 2015 - 22:04:11)

 
 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