Представьте себе, что есть база данных SQLite с двумя таблицами «users» и «ranks», одна содержит имена пользователей и их ранг как число (и идентификатор пользователя), другая содержит те же номера рангов и имя ранга. Цель состоит в том, чтобы вывести html-таблицу с именем ранга и именами пользователей (и их ИД пользователя).
<?php
$db1 = new PDO('sqlite:database');
$db2 = new SQLite3('database');
$result = $db1->query("SELECT * FROM users ORDER BY rank DESC");
echo '<table><tr><td>rank</td><td>username</td><td>id</td></tr>';
$data = "";
foreach($result as $row){
$data .=
'<tr><td>'.$db2->querySingle("SELECT rankname FROM ranks WHERE ranknumber =".$row['rank']).'</td>'.
'<td>'.$row['name'].'</td>'.
'<td>'.$row['id'].'</td></tr>';
}
echo $data;
echo "</table>";
?>
этот код прекрасно работает в небольшом масштабе, вопрос заключается в его производительности, когда база данных переполнена. По сути, он делает новый запрос к базе данных для каждой выводимой строки первого запроса, верно? Я добавил использование $ data вместо того, чтобы выводить каждую строку по очереди только в том случае, если это может каким-то образом уменьшить количество запросов где-нибудь вдоль дороги, но я не уверен, что это даже даст какую-то положительную разницу. Я слишком неопытен в работе с базой данных и php, чтобы знать, какую нагрузку этот код будет оказывать на сервер и / или сеть, по сравнению с простым наличием 2 запросов рядом, будет ли мой код по существу выполнять сотни, если не тысячи запросов к базе данных, и как это повлияет на производительность? Кроме того, если это плохо, что я могу с этим поделать? Есть ли другой способ достичь тех же результатов без проблем с производительностью?
Что еще более важно, что, если я также заменю имя пользователя отображаемым именем из совершенно другой базы данных, отличной от SQLite (MySQL)? 201 запрос для отображения 100 пользователей, означает ли это массовое использование ресурсов?
Как общее практическое правило, выдача запроса является дорогостоящей операцией — она включает в себя большую работу на стороне базы данных (разбор, проверка синтаксиса, проверка разрешений, построение плана выполнения, дисковый ввод-вывод, сетевой трафик в и из БД и тд).
Конечно, ни одно правило не является на 100% пуленепробиваемым, и вы всегда должны тестировать свой конкретный вариант использования, но в большинстве случаев выполнение одного «большого» запроса будет значительно лучше, чем выполнение «маленьких» запросов. В вашем случае вы можете использовать join
Синтаксис для получения всех необходимых результатов в одном запросе:
SELECT users.*, ranks.rankname
FROM users
JOIN ranks ON users.rank = ranks.ranknumber
ORDER BY users.rank DESC
Других решений пока нет …