Я могу решить это с помощью нескольких foreach-заявлений, но навсегда загружает страницу, когда ее 26 учеников в каждом классе и некоторые предметы имеют до 13 radnummer. См. Примеры ниже.
Это то, что я предпочитаю вывод (строки и столбцы):
Проблема: нагрузка навсегда.
Вопрос: как мне ускорить и повысить эффективность?
Таблица первая, где я выбираю всех студентов в классе (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
)
Судя по ответам Per76, этот комментарий представляется эффективным решением:
Кажется, что ни одна из ваших таблиц MySQL не имеет индексов.
Итак... добавьте индексы в ваши SQL-таблицы. В идеале вы должны индексировать все столбцы, которые вы указываете, в любом WHERE
или в любом предложении JOIN
или любом ORDER BY
. Индексирование - это ключ к скорости 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
.
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
)
switch/case
over if/else
? В этом случае (без каламбура) использование switch/case
действительно делает код более читабельным, но все, что я прочитал по этому вопросу, в основном закончилось выводом, что нет реальной разницы в производительности.
switch
@MagnusEriksson считывает значение переменной только один раз и проверяет его в каждом случае . Руководство гласит: «В операторе switch условие оценивается только один раз, и результат сравнивается с каждым оператором case. В операторе elseif условие оценивается снова». Таким образом, переключатель будет немного более эффективным. Но я должен заявить, что все мои пункты, кроме индекса MySQL, будут лишь незначительными улучшениями. :-)