2013-09-08 3 views
0

Я пытаюсь ускорить работу этого PHP-кода. Я запускаю его через браузер на XAMPP, используя Apache и MYSQL.Производительность анализа JSON и загрузка в MYSQL

Моя проблема в том, что я читаю очень большой файл размером 2 ГБ JSON. Я не могу прочитать его за один раз, так как у меня недостаточно памяти, и поэтому я должен прочитать его по строке

Код читает JSON по строкам. Для каждой строки (фрагмент данных JSON) вызывается функция (Function parse_item), которая декодирует строку JSON, а затем открывает базу данных mysql и вставляет выбранные данные из декодированной строки JSON, а затем закрывает базу данных MySQL. Я знаю его вставку в базу данных, которая вызывает проблемы с производительностью, но не уверен, что делать. (Т. Е. Когда я удаляю базу данных и просто эхо декодированный JSON намного быстрее)

Код (сокращенный фрагмент) работает, но очень медленно ...

Может ли кто-нибудь помочь? Я новичок в PHP, поэтому любое объяснение в простых выражениях было бы с благодарностью принято.

Также ......., если я запустил это из командной строки (т.е. загрузил PHP на свой компьютер), будет ли он работать намного быстрее?

Благодаря Джону

//Parse Function 
function parse_item($string) { 

$data = json_decode($string); 


$uid=($data->JsonScheduleV1->CIF_train_uid); 
$stp=($data->JsonScheduleV1->CIF_stp_indicator);              
$head=($data->JsonScheduleV1->schedule_segment->signalling_id);  
$startlocation=($data->JsonScheduleV1->schedule_segment->schedule_location[0]->tiploc_code); 

require('connect_db.php'); 
mysqli_select_db($mysql_link,"timetable"); 
mysqli_query($mysql_link,"INSERT INTO railstp (uid,stp,head,startlocation) 
    VALUES ('$uid','$stp','$head','$startlocation')"); 
mysqli_close($mysql_link); 

if (is_null($data)) { 
    die("Json decoding failed with error: ". json_last_error()); 
} 

} 


$file = 'CIF_PA_TOC_FULL_DAILY_toc-full'; 

// Slices up the JSON into lines and then 
parse_item($string); 



// 

EDIT

У меня есть база данных InnoDB Есть 20 ключей - 2 представляют собой целые числа, 2 финики и текст остальных не уверены, сколько строк, но думает, более 1000 - не удалось запустить его достаточно долго

+0

Вы должны показать структуру своей таблицы. (Если это MyISAM или InnoDB, какие ключи, ...). Сколько у вас линий? С помощью одного вызова скрипта вы разбираете весь файл, вызывая 'parse_item' для каждой строки? –

+0

Добавили EDIT – user2635961

+0

Попробуйте использовать пакетную вставку, возможно, 100 - 1000 записей за раз? http://stackoverflow.com/questions/5526917/how-to-do-a-batch-insert-in-mysql – SamV

ответ

1

Создать соединение MySQL и закрыть его за parse_item() вызов функции будет тратить время на скрипт а также ваше if заявления есть достаточно делает функции !, так что я бы переписать код:

require('connect_db.php'); 
mysqli_select_db($mysql_link,"timetable"); 
function parse_item($string,&$mysql_link) { 
    $data = json_decode($string); 
    if (is_null($data)) { 
    mysqli_close($mysql_link);die("Json decoding failed with error: ". json_last_error()); 
    } 
    $uid=($data->JsonScheduleV1->CIF_train_uid); 
    $stp=($data->JsonScheduleV1->CIF_stp_indicator);              
    $head=($data->JsonScheduleV1->schedule_segment->signalling_id);  
    $startlocation=($data->JsonScheduleV1->schedule_segment->schedule_location[0]->tiploc_code); 
    mysqli_query($mysql_link,"INSERT INTO railstp (uid,stp,head,startlocation) 
          VALUES ('$uid','$stp','$head','$startlocation')"); 
} 


$file = 'CIF_PA_TOC_FULL_DAILY_toc-full'; 
$handle = fopen("c:\\folder\$file" , "r"); 
while(!feof($handle)){ 
    $string=fgets($handle); 
    parse_item($string,$mysql_link);  //REMEMBER: to pass your $mysql_link variable! 
} 
fclose($handle); 
mysqli_close($mysql_link); 

Я надеюсь, что это поможет вам.

+0

Привет Saber. Это блестяще. Большое увеличение скорости. Ключевым обучением было то, что вы показывали мне, как писать код, чтобы я не должен был открывать и закрывать базу данных. У меня есть несколько иной способ чтения файла (строка за строкой), прежде чем передавать его функции. Ваш ответ отлично помог. Спасибо – user2635961

+0

@ user2635961 yw;), я использовал дескриптор файла, чтобы показать вам, как вы можете использовать 'parse_item()'. Не забывайте принимать и голосовать правильно и ваш подходящий ответ. Удача – 01e

+0

Спасибо, Сабер.Пытался проголосовать, но похоже, что мне нужна репутация 15, прежде чем делать это. Сделаю это, когда я доберусь до 15. – user2635961