2016-11-13 3 views
1

У меня есть настройка PHP-скрипта, которая анализирует файл JSON, который разбивается на несколько страниц.MySQL multi_query Очень медленно, альтернатива для простого запроса на усечение?

Этот PHP-скрипт анализирует JSON и вставляет его в базу данных MySQL.

На одном запросе ... (без TRUNCATE заявления):

if ($count > 0) { 

//check toperform operation 

foreach ($jsondecode as $entries) { 

//getting variables here 

$sql = "INSERT INTO table (title, handle, imagesrc) 
VALUES ('".$title."', '".$handle."', '".$imagesrc."')"; 

if ($connect->query($sql) === TRUE) { 
echo "New record created successfully"; 
} else { 
echo "Error: " . $sql . "<br>" . $connect->error; 
} 
} 
} 

успешно Результаты с script execution time: 16.451724052429

На multi_query ....:

if ($count > 0) { 
    $sql = "TRUNCATE table;"; 

foreach ($jsondecode as $entries) { 

//getting variables here 

$sql.= "INSERT INTO table (title, handle, imagesrc) 
VALUES ('".$title."', '".$handle."', '".$imagesrc."')"; 

if (!$mysqli->multi_query($sql)) { 
echo "Multi query failed: (" . $mysqli->errno . ") " . $mysqli->error; 
} 

do { 
if ($res = $mysqli->store_result()) { 
    var_dump($res->fetch_all(MYSQLI_ASSOC)); 
    $res->free(); 
} 
} while ($mysqli->more_results() && $mysqli->next_result()); 


} 
} 

Результаты успешно с script execution time: 278.05182099342, почти 5 минут.

Все, что я пытаюсь сделать, это TRUNCATE таблица перед INSERT.

Я собираюсь запустить это на задании CRON веб-сервера, который будет выполнять этот скрипт каждые 12 часов.

Существует, очевидно, такая огромная разница во времени выполнения в одном запросе и многопроцессовом ... есть ли что-нибудь, что я могу сделать?

Моя единственная мысль - установить еще один скрипт задания CRON, который просто выполняет оператор TRUNCATE каждые 12 часов, но за 1 минуту до этого основного запуска. Кажется, что это должно сработать ... но, конечно, не идеально, так как тогда мне придется иметь дело с несколькими сценариями, а не с одним.

+1

Несмотря на то, что вы не можете ответить на ваши вопросы, но вы можете запятой отдельно отнести свои значения вставки и запустить его как один запрос для нескольких элементов. например, 'значения (a, b, c), (d, e, f), (g, h, i)' – Scuzzy

+1

Выполните 'insert' после того, как запрос будет построен, а не для каждой итерации. – chris85

ответ

1

Причина такой огромной разницы в наличии одного дополнительного символа!

$sql.= "INSERT INTO table (title, handle, imagesrc) 
VALUES ('".$title."', '".$handle."', '".$imagesrc."')"; 

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

Вы обрезаете таблицу для каждой строки ввода в своем JSON, а затем снова вставляете все это.

Кроме того, это действительно не тот случай, когда вы должны использовать несколько запросов. Запустите запрос truncate вне цикла. Затем запустите запрос вставки внутри цикла.

Как уже указывалось, создание единого запроса на вставку с несколькими наборами VALUES может быть немного быстрее. В качестве альтернативы вы можете отключить автоматическую фиксацию транзакции и включить ее в конце.

if ($count > 0) { 
    $connect->query('TRUNCATE `table`'); 

    //check toperform operation 

    foreach ($jsondecode as $entries) { 

     //getting variables here 

     $sql = "INSERT INTO `table` (title, handle, imagesrc) 
     VALUES ('".$title."', '".$handle."', '".$imagesrc."')"; 

     if ($connect->query($sql) === TRUE) { 
      echo "New record created successfully"; 
     } else { 
      echo "Error: " . $sql . "<br>" . $connect->error; 
     } 

    } 
} 
+0

Спасибо за ответ. Можете ли вы уточнить? Я пытаюсь обернуть голову вокруг этого. Вы говорите, что причиной является присутствие одного дополнительного персонажа? О каком характере вы говорите ...? Что-то нужно отступать? Также оператор TRUNCATE выполняется вне цикла (после оператора IF и перед циклом FOREACH). Я работаю над одним вставным запросом, но это занимает некоторое время, оно должно ускорить работу.Спасибо за советы всем – bbruman

+0

Также вы говорите, что это не тот случай, когда я должен использовать несколько запросов, но тогда вы говорите, что запустите запрос TRUNCATE за пределами цикла ... а затем еще один запрос INSERT в цикле? Это два множественных утверждения .... У меня создалось впечатление, что для выполнения двух операторов, подобных этому, MULTI_QUERY - мой единственный вариант? – bbruman

+0

nopes. Это не многопроцессорные запросы. Подобно тому, как вы можете вводить различные запросы в консоль phpmysadmin или mysql, вы можете передавать запросы один за другим - точно так же, как вы делаете в своей первой версии. – e4c5

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