Вставить в БД данные из большого файла за приемлемое время

Sanchez

Новичок
Вставить в БД данные из большого файла за приемлемое время

Привет, есть XML-прайс, который генерит 1-с. Структура такова: сначала идут теги с ценой и ID, затем - тем же ID и названием, затем - тем же ID и производителем. Нужно вставить данные из файла в базу данных.
Сначала сделал в лоб - для цены и ID - INSERT, а потом для названия - UPDATE по тому ID, потом для производителя - UPDATE по тому же ID. Но конечно работает ужасно медленно (там около 10.000 записей). бОльшую часть времени съедают апдейты.
Пока думаю сделать так: предварительно данные собрать в самом скрипте, т.е. например через массив - составил его в том месте, где был INSERT, затем вместо апдейтов - дополнить данными (названием и производителем), предварительно отсортировав, чтоб можно было искать ID двоичным поиском. А затем уже перебирая массив, строить Инсерты, и вставлять данные в БД. Таким образом избавляемся от части, съедающей 99% времени - апдейтов.

Но может есть более красивое решение?
 

Фанат

oncle terrible
Команда форума
более красивое - враг красивого.

-~{}~ 02.05.07 20:41:

зачем что-то искать двоичным поиском?
 

Sanchez

Новичок
Например массив представляет собой таблицу, первая колонка - id, а потом через некоторое время мне для какого-то id нужно в соответсвующую ему строку записать значение. Как мне его искать, не полным же перебором (там много записей).
 

Sergey_Al

Новичок
Делаем три массива: цена, название, производитель. Ключи - id. Потом сортировка всех по ключу и вставляем.
 

Sanchez

Новичок
Я не уверен, что нет такой ситуации, когда например для цены ключ есть, а соответствующее ему название - отсутствует. А так будет сдвиг и переполох :)
 

Sergey_Al

Новичок
Во время втавки делать дополнительную проверку на то, что ключи одинаковые.

-~{}~ 03.05.07 02:17:

Ещё один способ с использованием
"LOAD DATA INFILE "data.txt" INTO TABLE db2.my_table;".
Он вероятно будет быстрее и подходит для случая, когда памяти не хватает.

Делаем файл со строками вида id, название, производитель. Только вместо запятой таб.
Делаем его так: сначало только id, а вместо name & company пробелы. Потом берём порцию названий, последовательный проход по файлу и при совпадении ид - запись названия в файл и т.д. Тоже самое с производителями. Чем больше порции, тем в итоге быстрее, т.к. меньше проходов по файлу.

Ну а LOAD DATA INFILE, как написано в мане, работает с очень высокой скоростью.

-~{}~ 03.05.07 02:29:

Совсем забыл, пустые записи (или битые), потом можно удалить одним запросом.
 

Sanchez

Новичок
Основное время займет процесс записи названия в файл, т.к. нужно найти позицию КУДА записывать (из 10.000). И так 10.000 раз! Вот и считай :)
Сейчас то же самое - 10.000 апдейтов - каждый из них ищет среди 10.000 записей. Вот я и оптимизирую))
 

Sergey_Al

Новичок
Нет, ты не понял, не 10 тыщ раз будем искать куда записывать. Берём порцию, например 100 названий, делаем один проход по файлу и одновременно записываем. Итого получаеся 100 проходов по файлу, или 10.000 * 100 итераций со сравнением и записью, что не так и много.
 

dark-demon

d(^-^)b
$data= array (
[15] => array('name'=>'имя','vendor'=>'производитель','cost'=>'цена'),
[54] => array('name'=>'имя','vendor'=>'производитель','cost'=>'цена'),
[75] => array('name'=>'имя','vendor'=>'производитель','cost'=>'цена'),
[43] => array('name'=>'имя','vendor'=>'производитель','cost'=>'цена'),
)

потом стартуем транзакцию, через foreach инсертим и завершаем транзакцию.
 

Фанат

oncle terrible
Команда форума
Sanchez
открою тебе страшную тайну. у элемента массива в пхп есть не только значение, но и ключ
 

Alexandre

PHPПенсионер
ривет, есть XML-прайс, который генерит 1-с.
я эту проблему решал более изящно. писал плагин для 1С, который
генерил более красивый прайс и не мучился с его распарсиванием.

Пример кода генерации прайса http://edocs.phpclub.net/1c/
 

Sergey_Al

Новичок
Sanchez, ты можешь файл для 10.000 сгенерировать очень просто, если сразу сохранить смещения строк. Тогда сложность построения файла будет всего 3*10.000 итераций.
 
Сверху