Ошибка тайм-аута при выполнении большого выбора из цикла - PullRequest
0 голосов
/ 06 августа 2020

У меня есть простой php код ниже

$sql_items = "SELECT id FROM item_masterfile"; /* this query has 7000 rows */

$result_items = mysqli_query($con,$sql_items);
    while ($row_items  = mysqli_fetch_row($result_items)) {
        $sql_qty = "SELECT qty FROM inventory WHERE id = ".$row_items[0];
        /* rest of the code here */
    }
}

он работает, но из-за большого количества данных мой сервер не может его обработать, и на другие запросы потребовалось много времени, чтобы ответить. Как я могу это исправить? Моя цель здесь как выбор партии? чтобы предотвратить засорение?

В процессе я вижу много выбора, ожидающего запуска.

Как я могу это исправить?

Ответы [ 4 ]

0 голосов
/ 06 августа 2020

Попробуйте выполнить следующий шаг:

  1. получить результат первого запроса и получить значения идентификатора, такие как (1,2,3,4, ...) ..
  2. и далее сторона где предложение выполняет второй запрос с WHERE условием IN предложением

Like

$sql_items = "SELECT id FROM item_masterfile"; /* this query has 7000 rows */

$result_items = mysqli_query($con,$sql_items);
    while ($row_items  = mysqli_fetch_row($result_items)) {
        $ids[] = $row_items['id'];
    }

    $sql_qty = "SELECT qty FROM inventory WHERE id IN  ".$ids;
      /* rest of the code here */
}

0 голосов
/ 06 августа 2020

Код в вашем вопросе показывает, что между таблицами существует связь one_to_one или one_to_many, поэтому использование разбиения на страницы и оператора соединения решит проблему. Проверьте приведенный ниже код, надеюсь, он будет полезным

$sql = "
     SELECT im.id, i.qty 
     FROM item_masterfile AS im 
     JOIN inventory AS i ON 
     im.id = i.item_masterfile_id 
     LIMIT $offset, $limit
";
$result_items = mysqli_query($con,$sql);

вы можете динамически установить $ offset и $ limit в своем коде и go на ...

0 голосов
/ 06 августа 2020

Вместо того, чтобы использовать l oop и указывать там id, вы должны собрать все идентификаторы в массив, а затем передать их все в запрос в одном go с помощью оператора IN.

Пример: SELECT qty FROM inventory WHERE id IN (1,2,3,4,5). Делая это, вы можете избежать l oop, и ваш код не выйдет с ошибкой тайм-аута.

OR

Вы можете добиться того же, используя подзапрос с вашим основным запросом

Пример: SELECT qty FROM inventory WHERE id IN (SELECT id FROM item_masterfile)

0 голосов
/ 06 августа 2020

попробуйте с партиями, используя предел и смещение, как показано ниже

$offset = $i * 5000; // $i is run batch number .. 1, 2, 3 etc in the foreach() loop.

if ($i == 0) {
  $offset = "";
}
$result_items="SELECT id FROM item_masterfile LIMIT 5000 OFFSET $offset;";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...