Как выполнить несколько mysqli_multi_queries?

Я пытаюсь прочитать большой файл XML и ВСТАВИТЬ все данные в базу данных. Я пробую 3 разных сценария (и мне нужна помощь с третьим):

  1. После каждого элемента XML я делаю один запрос: $this->mysqli->query($sql);
  2. Я добавляю все INSERT к переменной $sql и после цикла использую один мультизапрос $this->mysqli->multi_query($sql); для ВСТАВКИ всех сразу.

Я провел тесты, и оба сценария мне не нравятся:

  1. Вставляет все данные в БД, но работает 113 секунд. Это не большая проблема, но я хочу сделать лучше!
  2. Это вариант, который я использую для своих небольших XML-файлов, и он творит чудеса. Для одной из моих функций это сократило время выполнения с 6,5 до 0,17 с и так же точно. Проблема с этим файлом заключается в следующем: этот пакет $sql становится слишком большим, и сценарий становится нестабильным, вывод неверен.

Итак, теперь я придумал третье, гибридное решение. Но это не работает, как ожидалось. Идея заключается в том, чтобы создавать вызов $this->mysqli->muli_query($sql); после каждых 200 элементов, а затем перезапускать процесс. Я думаю, что мне не хватает правильного понимания функции mysqli->multi_query, потому что для меня приведенный ниже код имеет смысл. Но, может быть, мне нужно что-то освободить / point / next()?

В любом случае: после запуска скрипта база не заполняется полностью.

Как указано ниже моего кода:

if ($xmlObj) {
        $sql = "";
        $i = 1;
        foreach ($xmlObj->Response->FeaturesList->Feature as $feature) {
            $sid = $feature["ID"];
            $sql .= "INSERT INTO ...;";
            // Hybrid solution
            if (($i % 200) == 0) {
                $this->mysqli->multi_query($sql);
                $sql = "";
            }
            $i++;
        }
        // Hybrid: Update the leftovers
        $this->mysqli->multi_query($sql);
    }

ОБНОВЛЕНИЕ Вариант № 4, добавленный Михаем, отлично работает. Я создал строку INSERT..VALUES(a),(b),(c) и добавил, что использование mysqli->query() работает 10 секунд и добавляет все элементы. Спасибо

Однако вопрос о загадке multi_query остается!


person Hans Wassink    schedule 03.08.2015    source источник
comment
Другой вариант, который может быть быстрее: создайте запрос INSERT..VALUES (a), (b), (c), чтобы вы попали в свою таблицу только один раз.   -  person Mihai    schedule 03.08.2015
comment
Спасибо за вариант. Хотя код упрощен. Для каждой функции я также добавляю запросы INSERT в языковую таблицу. Так что это не так просто, но я, очевидно, могу создать для них вторую переменную $sql2. Не столкнусь ли я с той же проблемой с пакетами?   -  person Hans Wassink    schedule 03.08.2015
comment
Я не уверен, в чем именно заключается ошибка пакетов, но, возможно, вы можете настроить некоторые переменные php или mysql, чтобы справиться с этим. Однако я не уверен, что только один вызов БД быстрее, чем 200.   -  person Mihai    schedule 03.08.2015
comment
Я согласен, что это быстрее, поэтому я пытаюсь это сделать :D Ошибка пакета в основном говорит о том, что строка SQL, которую я передаю, слишком велика. Я могу настроить его только так много. Я уже пробовал это, но мне кажется, что если он занимает слишком много памяти или размера, вам нужно переосмыслить свой код, а не обновлять ограничения. Я попробую ваш вариант в качестве сценария 4 и дам вам знать, как он работает! Но вопрос остался :D   -  person Hans Wassink    schedule 03.08.2015
comment
Или, может быть, вы можете использовать эту опцию dev.mysql.com/doc /refman/5.5/en/load-xml.html   -  person Mihai    schedule 03.08.2015
comment
Если я могу составить карту, это может быть быстрее. XML построен не так, как в примере, много разных имен полей и т. д. Попробую, спасибо   -  person Hans Wassink    schedule 03.08.2015
comment
Что касается тайны: вы, вероятно, достигли предела max_allowed_packet.   -  person Marek    schedule 04.08.2015
comment
На самом деле это не загадка: D Я указал на это в своем посте. Но я просто хочу знать, почему нельзя чаще использовать multi_query.   -  person Hans Wassink    schedule 04.08.2015