Медленные запросы к базе

#1 15 августа 2012 в 09:15
Хостер лютует😊Предлагаю в теме поделиться своими знаниями (догадки оставим при себе joke) по поводу самых тяжелых запросов к базе.
Тему instantcms.ru/forum/thread9203.html перечитал...

У себя:
1. поправил запрос получения новых комментов (LIMIT 70), мне хватает 10.
2. убрал вывод комментов гостей
3. убрал лишние галочки категорий (не использую FAQ)
4. поставил максимально возможное кеширование
5. применил хак, когда кэш обновляется только для авторизованных пользователей (автор вроде Sjen, найти у него в блоге не могу...)
6. и этот instantcms.ru/blogs/poleznosti-ot-sjen/hak-optimizacija-vyvoda-komentariev.html

В какую еще сторону смотреть?
#2 15 августа 2012 в 09:49
/core/classes/db.class.php — function query :
  1. public function query($sql, $ignore_errors=false){
  2.  
  3. $inConf = cmsConfig::getInstance();
  4.  
  5. $sql = $this->replacePrefix($sql);
  6.  
  7. if ($inConf->debug){
  8.  
  9. $mtime = microtime();
  10.  
  11. $mtime = explode(" ",$mtime);
  12.  
  13. $mtime = $mtime[1] + $mtime[0];
  14.  
  15. $tstart = $mtime;
  16.  
  17. }
  18.  
  19. $result = mysql_query($sql, $this->db_link);
  20.  
  21. if ($inConf->debug){
  22.  
  23. $mtime = microtime();
  24.  
  25. $mtime = explode(" ",$mtime);
  26.  
  27. $mtime = $mtime[1] + $mtime[0];
  28.  
  29. $tend = $mtime;
  30.  
  31. $tpassed = ($tend - $tstart);
  32.  
  33. }
  34.  
  35. if ($inConf->debug){
  36.  
  37. $this->q_count += 1;
  38.  
  39. $this->q_dump .= '<pre>'.$sql.' <b style="color:'.($tpassed<0.1 ? 'green' : 'red').';">'.$tpassed.' сек.</b></pre><hr/>';
  40.  
  41. }
  42.  
  43.  
  44.  
  45. if (mysql_error() && $inConf->debug && !$ignore_errors){
  46.  
  47. die('<div style="margin:2px;border:solid 1px gray;padding:10px">DATABASE ERROR: <pre>'.$sql.'</pre>'.mysql_error().'</div>');
  48.  
  49. }
  50.  
  51.  
  52.  
  53. return $result;
  54.  
  55. }
Меняете функцию, включаете режим отладки и ищете свои медленные запросы. Целые числа с E посередине — они очень маленькие, не обращайте на них внимания.
#3 16 августа 2012 в 08:58

5. применил хак, когда кэш обновляется только для авторизованных пользователей (автор вроде Sjen, найти у него в блоге не могу...)

Евгений
вот тут про кэширование

я еще кэшировал для всех юзеров результаты некоторых запросов — ну, например, настройки модулей и компонентов, количество модулей/компонентов. ЗАпросы очень частые и выдают одно и то же, нет необходимости постоянно дергать ради них mysql. Тем самым в несколько раз уменьшал количество запросов на странице. Делал это с помощью той же самой библиотеки для кэширования, что указал по ссылке.
#4 17 августа 2012 в 12:25
мда...
Спасибо lokanaft за модификацию функции… как и думал, основные нагрузки создает форум… Можно что то сделать с запросом этим?

  1.  
  2.  
  3. SELECT p.pubdate, p.id AS post_id,
  4. u.id AS uid, u.nickname AS author,
  5. u.login AS author_login,
  6. t.title AS threadtitle, t.id AS threadid
  7. FROM cms_forum_posts p
  8. LEFT JOIN cms_forum_threads t ON t.id = p.thread_id AND t.is_hidden=0
  9. INNER JOIN cms_forums f ON f.id = t.forum_id
  10. LEFT JOIN cms_users u ON u.id = p.user_id
  11. WHERE (f.NSLeft >= 94 AND f.NSRight <= 95)
  12. ORDER BY p.id DESC
  13. LIMIT 1
  14.  
  15.  
выполняется аж пол секунды… 0,4595160484314 сек.
#5 17 августа 2012 в 12:26
И такой
  1.  
  2.  
  3. SELECT p.id
  4. FROM cms_forum_posts p
  5. INNER JOIN cms_forum_threads t ON t.id = p.thread_id
  6. INNER JOIN cms_forums f ON f.id = t.forum_id AND f.NSLeft >= '94' AND f.NSRight <= '95' AND f.published = 1
  7.  
  8.  
0,11964106559753 сек.
#6 17 августа 2012 в 13:12
Вот человек нашёл решение: instantcms.ru/forum/thread11739-2.html#96696. Возможно у вас тоже индексы почему то не учитываются.
#7 19 августа 2012 в 19:15

Возможно у вас тоже индексы почему то не учитываются.

lokanaft
прописал. Не помогло. Долгие запросы остались...

#8 20 августа 2012 в 11:01
Хотел спросить сколько запросов у Вас делает главная страница форума, просто у меня было вот на этом сайте forex.osobye.ru на главной форума была 1200 запрос страница грузилась 16сек., после того как я переписал запросы и сократил всего до 3 на страницу форума стало 0.5190 сек.

Ваши медленные запросы нужно проверять не только так нужно просто в phpmyadmine или аналогичной программе сделать EXPLAIN запроса и посмотреть что в нем не так, ну и следовательно уже или добавлять новые индексы или просто заменить данный запрос на другой менее прожорливый.
#9 20 августа 2012 в 11:40

сколько запросов у Вас делает главная страница форума

maxisoft

Время генерации страницы: 1.2458 сек.
Запросы к базе: 323

На форуме просто 1600 тем, 135 тысяч сообщений… Или при настроенных индексах это не существенно?
#10 20 августа 2012 в 12:19
нужно смотреть експлайн, счас сложно что то Вам предложить нужно проверить запросы и проанализировать данные. но при нормальных индексах будет все равно столько тем и сообщении.
#11 20 августа 2012 в 18:14

я еще кэшировал для всех юзеров результаты некоторых запросов — ну, например, настройки модулей и компонентов, количество модулей/компонентов. ЗАпросы очень частые и выдают одно и то же, нет необходимости постоянно дергать ради них mysql. Тем самым в несколько раз уменьшал количество запросов на странице. Делал это с помощью той же самой библиотеки для кэширования, что указал по ссылке.

SJen
Да, если смотреть отладку то запросы в таблицу модулей вносят свою приличную лепту в задержки, их бы в кеш
#12 20 августа 2012 в 18:19

прописал. Не помогло. Долгие запросы остались...

Евгений
Как сказал maxisoft, нужно в консоли или в phpmyadmin перед SELECT добавить EXPLAIN и смотреть какие поля в запросе без индексов обрабатываются ну и для них индексы указать через USE или FORCE
#13 6 сентября 2012 в 20:39
не знаю насколько актуально на данный момент, но помнится что обычные индексы в случае сортировки по первичному ключу не учитываются. попробуйте создать покрывающий индекс.
#14 6 сентября 2012 в 21:49
Самые "тяжелые" c JOIN, то есть те которые с нескольких таблиц делают выборку, вот как их победить
#15 6 сентября 2012 в 22:09

Самые "тяжелые" c JOIN, то есть те которые с нескольких таблиц делают выборку, вот как их победить

eoleg
не слышал про то что они тяжелые если раставить правильно индексы, ну и еще пару полезных мелочей при оптимизации сделать: типо выборка тех полей который нужны, запись в ковычках `, ну и явно указывать поля через таблицу… т.е нужно нам поле `name` которые лежит в таблице `user_names` при вызове лучше записать
  1. SELECT `user_names`.`name` FROM ..
еще как вариант при выполнение запроса провести профилирование и посмотреть на что уходит время — полезно при оптимизации;)

к примеру у меня на 2 миллиона записей, запрос с 5 JOIN'aми выполняется всего лишь 0.3с.
Вы не можете отвечать в этой теме.
Войдите или зарегистрируйтесь, чтобы писать на форуме.
Используя этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.