#php #mysql #pdo
#php #mysql — сервер #pdo ( пдо )
Вопрос:
Несколько лет назад я создал простую систему t-card для работы, и с тех пор она работает по назначению (обрабатывает около 300 заданий), сейчас она далека от совершенства, и поэтому, учитывая рост рабочей нагрузки за последние несколько месяцев из-за пандемии (обрабатывает около 2000 заданий), время загрузки значительно замедлилось с 30 секунд (в любом случае, не очень большое) до иногда 10 минут или просто истекает время ожидания.
Итак, способ, которым он настроен в настоящее время, заключается в том, что я получаю все даты заданий с:
$getdates = $conn->prepare("SELECT delivery_date FROM orders INNER JOIN stages ON orders.id = stages.order_id WHERE isnull(stages.stage_8_name) GROUP BY delivery_date");
$getdates->execute();
if($getdates->rowCount()) {
foreach ($getdates->fetchAll(PDO::FETCH_ASSOC) as $row) {
$delivery_date = $row['delivery_date'];
$getdates_c = $conn->prepare("SELECT delivery_date FROM orders INNER JOIN stages ON orders.id = stages.order_id WHERE isnull(stages.stage_8_name) AND delivery_date = :delivery_date ");
$getdates_c->execute(array(':delivery_date' => $delivery_date));
$number_of_cards = $getdates_c->rowCount();
При этом будет получена дата для всех заданий, которые еще предстоит выполнить. Затем я создаю заголовок таблицы с каждой датой и количеством заданий на эту дату. Затем я проверяю, какие Драйверы недоступны в этот день с помощью:
$getstaff = $conn->prepare("SELECT * FROM staff WHERE position = 4 ORDER BY name asc");
$getstaff->execute();
foreach ($getstaff->fetchAll(PDO::FETCH_ASSOC) as $row) {
$staff_id = $row['id'];
$gethol = $conn->prepare("SELECT * FROM staff_holiday WHERE staff_id = :staff_id AND day = :holday AND (type = 'Holiday' OR type = 'Holiday Half')");
$gethol->execute(array(':staff_id' => $staff_id, ':holday' => $delivery_date));
foreach ($gethol->fetchAll(PDO::FETCH_ASSOC) as $row) {
$type_hol = $row['type'];
$staff_id = $row['staff_id'];
И добавьте это в заголовок таблицы.
Затем я в основном повторяю запрос даты для тела таблицы с:
$getdates = $conn->prepare("SELECT delivery_date FROM orders INNER JOIN stages ON orders.id = stages.order_id WHERE isnull(stages.stage_8_name) GROUP BY delivery_date");
$getdates->execute();
if($getdates->rowCount()) {
foreach ($getdates->fetchAll(PDO::FETCH_ASSOC) as $row) {
$delivery_date = $row['delivery_date'];
а затем, используя эту дату, пройдите цикл по массиву фургонов и получите количество заданий на фургон и создайте заголовок вложенной таблицы с номером фургона и количеством заданий:
$vans = array(0,1,2,3,4,5);
foreach ($vans as $this_van) {
$sql = "SELECT count(*) FROM `orders` INNER JOIN stages ON orders.id = stages.order_id WHERE isnull(stages.stage_8_name) AND orders.delivery_date = :delivery_date AND orders.van = :this_van ";
$result = $conn->prepare($sql);
$result->execute(array(':delivery_date' => $delivery_date,':this_van' => $this_van ));
$number_of_rows = $result->fetchColumn();
затем, наконец, я получаю все задания для каждого фургона на этот конкретный день и перечисляю их в порядке выполнения:
$getproduction = $conn->prepare("SELECT orders.about 20 different fields, stages.another 20 fields FROM orders INNER JOIN stages ON orders.id = stages.order_id WHERE isnull(stages.stage_8_name) AND orders.delivery_date = :delivery_date AND orders.van = :this_van ORDER BY drop_no ASC");
$getproduction->bindParam(':delivery_date', $delivery_date);
$getproduction->bindParam(':this_van', $this_van);
$getproduction->execute();
foreach ($getproduction->fetchAll(PDO::FETCH_ASSOC) as $row) {
$order_id = $row['id'];
итак, здесь перечислены все сведения об этой работе.
В итоге я получаю список дат с номерами фургонов ниже и рабочих мест, перечисленных под номерами фургонов.
Любая помощь в упрощении этого или просто ускорении его выполнения была бы замечательной. Спасибо.
РЕДАКТИРОВАТЬ: Хорошо, основываясь на ваших комментариях, я сократил все до тестирования и пока получил это:
// Gets all orders and sorts by drop number
$getorders = $conn->prepare("SELECT * FROM orders INNER JOIN customers ON orders.customer_id = customers.customer_id INNER JOIN addresses on orders.address_id = addresses.address_id ORDER BY drop_no");
$getorders->execute();
$result = $getorders->fetchAll(PDO::FETCH_ASSOC);
// groups order by date, van, drop
foreach ( $result as $value ) {
$group[$value['delivery_date']][$value['van_no']][$value['drop_no']][] = $value;
}
// outputs orders by date -> van -> drop
var_dump($group);
вот так:
array (size=2)
'2020-08-25' =>
array (size=2)
1 =>
array (size=3)
0 =>
array (size=8)
'orders_id' => string '6' (length=1)
'customer_id' => string '1' (length=1)
'address_id' => string '1' (length=1)
'van_no' => string '1' (length=1)
'drop_no' => string '0' (length=1)
'delivery_date' => string '2020-08-25' (length=10)
'customer_name' => string 'One' (length=3)
'address_postcode' => string 'b1' (length=2)
1 =>
array (size=8)
'orders_id' => string '1' (length=1)
'customer_id' => string '1' (length=1)
'address_id' => string '1' (length=1)
'van_no' => string '1' (length=1)
'drop_no' => string '1' (length=1)
'delivery_date' => string '2020-08-25' (length=10)
'customer_name' => string 'One' (length=3)
'address_postcode' => string 'b1' (length=2)
Любая помощь в том, как я бы напечатал заголовок delivery_date, а затем подзаголовок van_no со всеми заданиями, напечатанными под их van_no в порядке drop_no? все, что я использую для эхо-вывода, повторяет дату и значение van для каждого задания.
Еще раз спасибо.
Комментарии:
1. 1) 2-й запрос в 1-м фрагменте кода кажется бессмысленным. У вас уже есть эта информация из 1-го запроса. 2) если у вас есть цикл foreach, основанный на результате запроса, в котором вы выдаете другой запрос, то вы в основном реализовали объединение базы данных в php. Выполните объединение в базе данных. 3) повторять один и тот же запрос снова и снова — пустая трата времени и ресурсов. Просто сохраните результаты в массиве, чтобы повторно использовать значения без повторения запроса.
2. ДА. Смотрите о соединениях (снова) и обратите внимание, что при отсутствии каких-либо агрегирующих функций предложение GROUP BY никогда не подходит.
3. @Strawberry в OP используется group by вместо distinct, так что с oart все в порядке. Хотя добавление count(*) может помочь в случае с первым фрагментом кода.
4. @Shadow Эта часть не в порядке!