2009-06-25 4 views
3

У меня есть тысячи данных, обработанных из огромного XML, которые нужно вставить в таблицу базы данных, используя PHP и MySQL. Моя проблема - слишком много времени, чтобы вставить все данные в таблицу. Есть ли способ, чтобы мои данные были разделены на меньшую группу, чтобы процесс вставки по группам? Как настроить скрипт, который будет обрабатывать данные на 100, например? Вот мой код:Пакетная вставка данных в базу данных MySQL с использованием php

foreach($itemList as $key => $item){ 
    $download_records = new DownloadRecords(); 
    //check first if the content exists 
    if(!$download_records->selectRecordsFromCondition("WHERE Guid=".$guid."")){ 
     /* do an insert here */ 
    } else { 
     /*do an update */ 
    } 

}

* примечание: $ ITEMLIST составляет около 62000 и продолжает расти.

ответ

3

Использование петли для петли?

Но самый быстрый способ загрузки данных в MySQL - использовать команду LOAD DATA INFILE, вы можете создать файл для загрузки через PHP, а затем передать его в MySQL через другой процесс (или в качестве последнего шага в исходном процессе) ,

Если вы не можете использовать файл, используйте следующий синтаксис:

insert into table(col1, col2) VALUES (val1,val2), (val3,val4), (val5, val6) 

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

EDIT: Учитывая ваш фрагмент, кажется, что вы можете использовать синтаксис MySQL MySQL, позволяя базе данных выполнять работу и уменьшая количество запросов. Это предполагает, что ваша таблица имеет первичный ключ или уникальный индекс.

Бить БД каждые 100 строк вы можете сделать что-то вроде (ПОЖАЛУЙСТА, присоедините его к вашей среде)

$insertOrUpdateStatement1 = "INSERT INTO table (col1, col2) VALUES "; 
$insertOrUpdateStatement2 = "ON DUPLICATE KEY UPDATE "; 
$counter = 0; 
$queries = array(); 

foreach($itemList as $key => $item){ 
    $val1 = escape($item->col1); //escape is a function that will make 
           //the input safe from SQL injection. 
           //Depends on how are you accessing the DB 

    $val2 = escape($item->col2); 

    $queries[] = $insertOrUpdateStatement1. 
    "('$val1','$val2')".$insertOrUpdateStatement2. 
    "col1 = '$val1', col2 = '$val2'"; 

    $counter++; 

    if ($counter % 100 == 0) { 
     executeQueries($queries); 
     $queries = array(); 
     $counter = 0; 
    } 
} 

И executeQueries бы захватить массив и отправить один множественный запрос:

function executeQueries($queries) { 
    $data = ""; 
    foreach ($queries as $query) { 
     $data.=$query.";\n"; 
    } 
    executeQuery($data); 
} 
+0

Да, я использую цикл for для вставки данных в удаленную базу данных. Также проблема заключается в том, что я использую удаленную базу данных, поэтому мой скрипт работает на отдельном сервере для подачи другой базы данных, которая также работает на отдельном сервере. – text

+0

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

+0

Да, я могу использовать файл, и это то, что я планирую. У меня есть проблема с этой вставкой, как я могу повторить вставку в таблицу (col) VALUES (val) для повторения после достижения 100 строк? – text

0

Да, просто делайте то, что вы ожидаете делать.

Вам не следует пытаться выполнять массовую вставку из веб-приложения, если вы считаете, что можете нанести вред тайм-ауту и ​​т. Д. Вместо этого запустите файл где-нибудь и получите демона или cron и т. Д., Заберите его и запустите пакетное задание (если выполняется от cron, убедитесь, что запускается только один экземпляр).

0

Вы должны поместить его, как указано ранее, в каталог temp с заданием cron для обработки файлов, чтобы избежать тайм-аутов (или потеря сети).

Используйте только веб-страницы для загрузки.

Если вы действительно хотите импортировать в БД по веб-запросу, вы можете либо сделать массовую вставку, либо использовать хотя бы транзакцию, которая должна быть быстрее.

Затем для ограничения вставок партиями 100 (совершение вашего trasnsaction, если счетчик считается% 100 == 0) и повторять до тех пор, пока все ваши строки не будут вставлены.

+0

как реализовать $ count% 100 = 0? Я использую файл для вывода данных в таблицу назначения. ВСТАВИТЬ В СТОИМОСТЬ ЗНАЧЕНИЙ (val), (val) .... (val); и повторить INSERT после того, как линии достигнут 100 или что-то еще? – text

+0

пример: CNX = mysql_connect() х = 0 в то время как (что-то вставить) сделать: fetch_values_from_file (X, Y, Z) cnx.exec ("вставить в табличных значений X, Y, Z", X , Y, Z) x + = 1 если x% 100: cnx.commit() – makapuf

Смежные вопросы