Страницы

Поиск по вопросам

среда, 5 февраля 2020 г.

Оптимизация mysql запросов

#php #оптимизация #mysql


Назрело несколько вопросов по оптимизации mysql запросов.

К примеру, на главной странице форума выводятся последние 5 сообщений. Формат такой:
форумная тема - короткий текст - ник - группа пользователя. До недавнего момента я
бы писал что-то типа такого:

/*
таблица posts: id, user_id, theme_id, text
таблица users: id, nick, group_id
таблица themes: id, name
таблица groups: id, name
*/
$posts = $db->execAndReturnAll('select `id`, `user_id`, `theme_id`, `text` from `posts`
order by `id` desc limit 5');

$users = array();
$themes = array();
$groups = array();

$l = sizeof($posts);
for($i = 0; $i < $l; ++$i)
{
if(!in_array($posts[$i]['user_id']), $users)
    $users[] = $posts[$i]['user_id'];
if(!in_array($posts[$i]['theme_id']), $themes)
    $themes[] = $posts[$i]['theme_id'];
}

$users = $db->execAndReturnAll('select `id`, `nick`, `group_id` from `users` where
`id` in (0,'.implode(',', $users).')');
$themes = $db->execAndReturnAll('select `id`, `name` from `themes` where `id` in
(0,'.implode(',', $themes).')');

$l = sizeof($users);
for($i = 0; $i < $l; ++$i)
{
if(!in_array($users[$i]['group_id']), $groups)
    $groups[] = $users[$i]['group_id'];
}

$groups = $db->execAndReturnAll('select `id`, `name` from `groups` where `id` in
(0,'.implode(',', $groups).')');

Но меня что-то берут сомнения, а целесообразно ли посылать 4 простых запроса к БД
или расходы на передачу запросов туда-обратно себя не окупят и лучше написать один
сложный запрос?

2) Стоит ли перекладывать на mysql всевозможные расчеты или лучше оставить это php?
То есть, что лучше:

$data = $db->execAndReturn('select `width`, `height`, `width`*`height` as `square`
from `rectangles` limit 1');

или

$data = $db->execAndReturn('select `width`, `height`, from `rectangles` limit 1');
$data['square'] = $data['width'] * $data['height'];

3) Есть ли какие-либо инструменты для тестирования скорости запросов к БД?
Заранее спасибо.    


Ответы

Ответ 1



В Вашем случае лучше написать один сложный. По поводу расчетов, mysql сделает их быстрее. Все таки php - это интерпритатор и любые лишние действия - это нагрузка. Но судя по Вашему коду, у Вас не нагруженный проект, так что такие действия (такие, как умножение) делайте там, где Вам удобнее :) Инструменты для тестирования: explain... и $start_time = microtime(true); // выполнение действий $exec_time = microtime(true) - $start_time;

Ответ 2



1) Зависит от того, сколько данных возвращается в ответах на эти запросы и где находится сервер БД (на той же машине или где-то в сети), тогда, возможно, стоит ориентироваться на скорость передачи данных и загрузку канала. UPD->Regarding Alex Silaev Например в данном случае (привожу только маленький пример): 'select `id`, `nick`, `group_id` from `users` where `id` in (0,'.implode(',', $users).')' Лучше поправить в один запрос, который выполнится на стороне MySQL: 'select `id`, `nick`, `group_id` from `users` where `id` in (select `user_id`from `posts` order by `id` desc limit 5)' Как-то так, просто для примера. 2)По моему мнению, стоит. На сегодняшний день существует множество агрегатных функций, которые с БД работают очень быстро и выводят данные с ошеломительной скоростью. Любая статистика выводится безумно быстро. 3) Была парочка инструментов, но уже не помню по склерозу. Вообще часто сталкивался с оптимизацией запросов, которые заносятся в журнал медленных запросов. Можно проанализировать переменные MySQL и статистику, выделив как быстро она (БД) работает, как эффективно используется память и т.п. Но это уже больше дело системного администратора.

Ответ 3



ну вообще по поводу выбора, то второй чуть лучше вариант! А вообще попробуйте поюзать вьюхи)

Ответ 4



phpmyadmin показывает время выполнения запроса, мне кажется очень удобным тестировать запросы в нем

Ответ 5



чем меньше запросов к mysql тем лучше. один сложный запрос всегда лучше, чем несколько простых. особенно нежелательно делать запросы в циклах. а вот где посчитать width*height большой разницы нет. можно с тем же успехом после выборки из базы, сделать цикл и в нем произвести вычисления. конечно, с обычным умножением и mysql справится легко, но бывают и более сложные операции, которые проще вынести на php. пример: $list = array(); $sqlRes = mysql_query("select height,width from ... "); while ($res = mysql_fetch_array($sqlRes)) { $res['square'] = $res['height']*$res['width']; $list[] = $res; }

Комментариев нет:

Отправить комментарий