Эффективный массив PHP и выберите

0

Я могу решить это с помощью нескольких foreach-заявлений, но навсегда загружает страницу, когда ее 26 учеников в каждом классе и некоторые предметы имеют до 13 radnummer. См. Примеры ниже.

Это то, что я предпочитаю вывод (строки и столбцы): Изображение 174551

Проблема: нагрузка навсегда.

Вопрос: как мне ускорить и повысить эффективность?

Таблица первая, где я выбираю всех студентов в классе (SELECT 1):

SELECT 'intressenter_alla'.id, 'intressenter_alla'.fornamn, 'intressenter_alla'.efternamn
FROM 'intressenter_alla' 
INNER JOIN 'klass_elev' 
ON 'intressenter_alla'.id = 'klass_elev'.id
WHERE ('klass_elev'.klass = :klassen)
ORDER BY 'intressenter_alla'.efternamn, 'intressenter_alla'.fornamn ASC

PRINT_R дает:

Array ( 

      [0] => Array ( 
      [id] => 1226 
      [0] => 1226 
      [lid] => 0 
      [1] => 0 
      [fornamn] => Peter
      [2] => Peter 
      [efternamn] => Strobe 
      [3] => Strobe 
      [personnr] => 070920-8690 
      [4] => 070920-8690 
      [mejl] => [email protected]  
      [5] => [email protected]  
      [6] => 1226 
      [klass] => 6B 
      [7] => 6B
)

      [1] => Array ( 
      [id] => 1227 
      [0] => 1227 
      [lid] => 0 
      [1] => 0 
      [fornamn] => Victor 
      [2] => Victor 
      [efternamn] =>Gand 
      [3] => Gand 
      [personnr] => 070518-8995 
      [4] => 070518-8995
      [mejl] => [email protected] 
      [5] => [email protected]
      [6] => 1227 
      [klass] => 6B 
      [7] => 6B
)
)

В таблице два, где я выбираю соответствующие данные каждому учащемуся. Здесь есть проблема. В этом примере каждый ученик должен иметь пять рядов radnummer (se ниже) для этого конкретного предмета. Появляется только последний. В каждой строке должно отображаться определенное значение kunsk_klick. См. Пример ниже (SELECT 2):

SELECT * 
FROM 'iup_kunskapskrav_klick' 
WHERE elev_id = ? AND radnummer = ? AND amne_id = ? AND arskurs = ?
ORDER BY radnummer, datum DESC

PRINT_R дает:

Array ( 
   [kunsk_id] => 138557
   [0] => 138557 
   [amne_id] => 1 
   [1] => 1 
   [radnummer] => 5 
   [2] => 5 
   [elev_id] => 1226 
   [3] => 1226 
   [arskurs] => 5 
   [4] => 5 
   [lid] => 1 
   [5] => 1 
   [kunsk_klick] => E 
   [6] => E 
   [datum] => 2018-05-29 
   [7] => 2018-05-29 
) 

Array ( 

   [kunsk_id] => 138561 
   [0] => 138561 
   [amne_id] => 1 
   [1] => 1 
   [radnummer] => 5 
   [2] => 5 
   [elev_id] => 1227 
   [3] => 1227 
   [arskurs] => 5 
   [4] => 5 
   [lid] => 1 
   [5] => 1 
   [kunsk_klick] => E 
   [6] => E 
   [datum] => 2018-05-29 
   [7] => 2018-05-29 
)

EDIT 1: структура таблиц.

Таблица intressenter_alla

CREATE TABLE 'intressenter_alla' (
  'id' int(4) NOT NULL,
  'lid' int(3) NOT NULL,
  'fornamn' varchar(255) NOT NULL,
  'efternamn' varchar(255) NOT NULL,
  'personnr' varchar(12) NOT NULL,
  'mejl' varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Таблица iup_kunskapskrav_klick

CREATE TABLE 'iup_kunskapskrav_klick' (
  'kunsk_id' int(11) UNSIGNED NOT NULL,
  'amne_id' int(3) NOT NULL,
  'radnummer' int(10) NOT NULL,
  'elev_id' int(3) NOT NULL,
  'arskurs' int(2) NOT NULL,
  'lid' int(3) NOT NULL,
  'kunsk_klick' varchar(3) COLLATE utf8_swedish_ci NOT NULL,
  'datum' date NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci;

Таблица klass_elev

CREATE TABLE 'klass_elev' (
  'id' int(5) NOT NULL,
  'klass' varchar(2) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Elevid och klass.';

EDIT 2: пример кода (я знаю, никакого хорошего смешивания PHP и HTML, плохой отступы тоже).

<?php

// All students (See SELECT number 1)
$hamta_hela_klassen = $anvandare->klasslista($_GET['klass']);

// Count how many radnummer there is in the subject
$count = 0;
$count = $abb->rakna_kunskapskrav($_GET['amne_id'], $arskursens);

echo "<table>";
echo "<thead>";
echo "<tr><th>Nr.</th><th>Picture</th><th>Name</th>";
if ($count<=1){
    echo "<th scope='row' style='vertical-align:middle;text-align:center'>Kunskapskrav</th>";
} else {
    for($i=1;$i<=$count;$i++)
    {
        // This outputs R1 - R2 and so on in the header of the columns (see the picture above)
        echo "<th width='1%' scope='row' style='vertical-align:middle;text-align:center'>R".$i."</th>";
    }
}

echo "<th>Date</th><th>Button</th>";

$raknare = 0;

// Loop out each student. Not the most effective way...                                                               
foreach ($hamta_hela_klassen as $klassuppgifter){
    $raknare++;

    // Profile picture
    $profilbild = '/home/jo/public_html/no/students/profilbilder/'.$klassuppgifter['id'].'.jpg';

    echo "<td>";
    echo AKTIV_URL."students/profilbilder/".$klassuppgifter['id'].".jpg";
    echo "</td>";

    // NAME
    echo "<td>";
    echo $klassuppgifter['fornamn']." ".$klassuppgifter['efternamn'];
    echo "</td>";

    if ($count<=1){
        echo "<td>Empty.</td>";
    } else {for($i=1;$i<=$count;$i++)
    {

        // Fetching each corresponding RADNUMMER for each student (see SELECT 2 above)                                      

        $iup_info_k1 = $iup->hamta_ett_kunskapskrav_klick_klass($klassuppgifter['id'], $i,$_GET['amne_id'], $arskursen);

        if (empty($iup_info_k1) && ($arskursen == '5' || $arskursen =='6' || $arskursen =='8' || $arskursen =='9')){
            $arskursen_lager = $arskursen -1;
            $iup_info = $iup->hamta_ett_kunskapskrav_klick_klass($klassuppgifter['id'], $i,$_GET['amne_id'], $arskursen_lager);
        } else {
            $iup_info = $iup_info_k1;
        }

        //Special for students in 4 - 5
        if ($arskursen=='4' || $arskursen=='5') {
            if ($iup_info['kunsk_klick'] == "G"){$betyget = 'P';}
            if ($iup_info['kunsk_klick'] == "F"){$betyget = 'O';}
            elseif ($iup_info['kunsk_klick'] == "E"){$betyget = '1';}
            elseif ($iup_info['kunsk_klick'] == "C"){$betyget = '2';}
            elseif ($iup_info['kunsk_klick'] == "A"){$betyget = '3';}
            elseif (empty($iup_info['kunsk_klick'])) {$betyget = "P"; }
        }

        //Special for students in 6 - 9
        if ($arskursen=='6' || $arskursen=='7' || $arskursen=='8' || $arskursen=='9') {
            if ($iup_info['kunsk_klick'] == "G"){$betyget = 'P';}
            elseif (empty($iup_info['kunsk_klick'])) {$betyget = "P"; }
            else { $betyget = $iup_info['kunsk_klick']; }
        }
        echo "<td>".$betyget."</td>";
    }
    }

    // DATE
    echo "<td>";
    echo $iup_info['datum'];
    echo "</td>";

    // Edit button
    echo "<td>";
    echo "EDIT";
    echo "</td>";


}

echo "</tr>";

echo "</tbody>";
echo "</table>";

?>

Редактировать 3:

Чтобы ТОЛЬКО выводить именованные данные столбца, а не данные числовых знаков, я меняю оператор выборки:

$pdo-> fetchAll (ПДО :: FETCH_ASSOC);

Теперь это выглядит так:

    Array ( 
       [kunsk_id] => 138561 
       [amne_id] => 1 
       [radnummer] => 5 
       [elev_id] => 1227 
       [arskurs] => 5 
       [lid] => 1 
       [kunsk_klick] => E 
       [datum] => 2018-05-29 
    )
  • 0
    Можете ли вы показать нам свой реальный код (а не только запросы)? Я предполагаю, что есть запросы в циклах? Кроме того, вы убедились, что ваши таблицы правильно проиндексированы? Это само по себе ускорит ваши запросы много.
  • 0
    Очень сложно следить за вопросом, не зная схемы базы данных. Не могли бы вы, например, реплицировать базу данных в SQL Fiddle ( sqlfiddle.com )?
Показать ещё 7 комментариев
Теги:
arrays

1 ответ

1
Лучший ответ

Судя по ответам Per76, этот комментарий представляется эффективным решением:

Кажется, что ни одна из ваших таблиц MySQL не имеет индексов.

Итак... добавьте индексы в ваши SQL-таблицы. В идеале вы должны индексировать все столбцы, которые вы указываете, в любом WHERE или в любом предложении JOIN или любом ORDER BY. Индексирование - это ключ к скорости MySQL.

Максимизация производительности запросов с помощью индексации столбцов в MySQL

Как работают индексы MySQL?

Как добавить индексы в таблицы MySQL?


ПРИМЕЧАНИЕ. Представленные здесь предложения - это микрооптимизация и будут лишь малейшим образом влиять на время загрузки страницы и/или эффективность. Это только твики, и их улучшения будут бледны по сравнению с улучшениями, полученными в результате внедрения правильной индексации столбцов в MySQL, как указано выше.

  • Используя switch PHP заявления вместо repetative elseif с.

        if ($iup_info['kunsk_klick'] == "F"){$betyget = 'O';}
        elseif ($iup_info['kunsk_klick'] == "E"){$betyget = '1';}
        elseif ($iup_info['kunsk_klick'] == "C"){$betyget = '2';}
        elseif ($iup_info['kunsk_klick'] == "A"){$betyget = '3';}
        elseif (empty($iup_info['kunsk_klick'])) {$betyget = "P"; }
    

    становится

        switch($iup_info['kunsk_klick']) {
             case "F":
                 $betyget = 'O';
                 break;
             case "E":
                 $betyget = '1';
                 break;
             case "C":
                 $betyget = '2';
                 break;
             case "A":
                 $betyget = '3';
                 break;
             case "":
                 $betyget = 'P';
                 break;
        }
    
  • Используйте правильный тип MySQL Integer для определения столбцов. Многие из столбцов INT с длиной всего 3, 4 или 5 столбцов могут быть UNSIGNED SMALLINT.

  • Объединяя типы данных столбцов MySQL, поэтому столбцы INT(4) сравниваются с другими столбцами INT(4) в предложениях JOIN и WHERE.
  • Использовать utf8mb4 символов и сортировки utf8mb4 а не дрянной 3-байтовый UTF-8 (huh? Wtf?)
  • Эффективность работы с типом в операторах if: (int)$arskursen===6 быстрее и эффективнее (крошечной отметкой), чем $arskursen=='6'
  • Исправьте свой PHP, чтобы ТОЛЬКО выводить именованные данные столбца, а не данные числовых знаков (вы играете с вдвое большим количеством данных, как это необходимо в PHP). Пример:

    Array ( 
       [kunsk_id] => 138561 
       [amne_id] => 1 
       [radnummer] => 5 
       [elev_id] => 1227 
       [arskurs] => 5 
       [lid] => 1 
       [kunsk_klick] => E 
       [datum] => 2018-05-29 
    )
    
  • 0
    Просто из любопытства, есть ли какое-нибудь упоминание об увеличении «эффективности» (которое вы упомянули в комментарии под ОП) для использования switch/case over if/else ? В этом случае (без каламбура) использование switch/case действительно делает код более читабельным, но все, что я прочитал по этому вопросу, в основном закончилось выводом, что нет реальной разницы в производительности.
  • 0
    switch @MagnusEriksson считывает значение переменной только один раз и проверяет его в каждом случае . Руководство гласит: «В операторе switch условие оценивается только один раз, и результат сравнивается с каждым оператором case. В операторе elseif условие оценивается снова». Таким образом, переключатель будет немного более эффективным. Но я должен заявить, что все мои пункты, кроме индекса MySQL, будут лишь незначительными улучшениями. :-)
Показать ещё 8 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню