Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Как оптимизировать запросы в mysql?

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Без описания
x-miller-x
Отправлено: 26 Апреля, 2017 - 06:36:20
Post Id


Новичок


Покинул форум
Сообщений всего: 52
Дата рег-ции: Апр. 2012  


Помог: 0 раз(а)




Есть запросы которые при меньшей нагрузке выполняются меньше секунды, потом как бывает некая нагрузка 300-400 юзеров онлайн, начинают выполнятся от 5 секунд до 120с+

Запрос №1
CODE (text):
скопировать код в буфер обмена
  1. SELECT count(DISTINCT product.id)
  2. FROM `product`
  3. JOIN `city` ON city.id=product.city_id
  4. JOIN `company` ON company.id=product.company_id
  5. WHERE ((((`product`.`id` in (
  6.           select product_id from product_to_city
  7.           join city on (city.id = product_to_city.city_id)
  8.           where city.id = 104 or city.parent_id = 104
  9.         )))) AND (`product`.`publish` = 1 AND `product`.`archive` != 1 AND `product`.`delete` != 1));


Запрос №2
CODE (text):
скопировать код в буфер обмена
  1. SELECT count(*)
  2. FROM (SELECT `product`.`id`, `product`.`position`, `product`.`description`, `product`.`city_id`,  `production`.`price`,  `production`.`company_id`, `company`.`company_type`, `city`.`name` AS `city_name`
  3. FROM `product_to_tag` `p2t`
  4. JOIN `product` ON product.id = p2t.product_id
  5. JOIN `product_to_city` `ptc` ON product.id = ptc.product_id
  6. JOIN `city` `c` ON c.id = ptc.city_id
  7. LEFT JOIN `city` `city` ON city.id=product.city_id
  8. LEFT JOIN `company` ON company.id=product.company_id
  9. WHERE ((((`product`.`id` in (
  10.           select product_id from product_to_city
  11.           join city on (city.id = product_to_city.city_id)
  12.           where city.id = 1 or city.parent_id = 1
  13.         )))) AND (`product`.`publish` = 1 AND `product`.`archive` != 1 AND `product`.`delete` != 1)) AND (product.id !=  513568) AND (c.id = 1 or c.parent_id = 1) AND ((`p2t`.`tag_id` IN (14, 30, 37, 500)))
  14. GROUP BY `product`.`id`
  15. ORDER BY `product`.`timestamp_update` DESC) as count;



в логах долгих запросов после второго запроса даже простые запросы медленно начинают выполнятся
CODE (text):
скопировать код в буфер обмена
  1.  
  2. # Query_time: 256.971239 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0
  3. UPDATE product SET `view_count` = `view_count` + 1 WHERE id = '2797283';
  4.  
  5. # Query_time: 554.572351 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0
  6. UPDATE product SET `view_count` = `view_count` + 1 WHERE id = '2156047';
  7.  
  8. # Query_time: 646.604457 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0
  9. UPDATE product SET `view_count` = `view_count` + 1 WHERE id = '2104649';


как еще оптимизировать? Индексы все расставлены

(Отредактировано автором: 26 Апреля, 2017 - 06:36:50)

 
 Top
Мелкий Супермодератор
Отправлено: 26 Апреля, 2017 - 09:04:06
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Первый запрос:
зачем вам вообще джойны и distinct? За отсечением отсутствующих городов и кампаний должны FK следить и не допускать такое в принципе. in subquery - в зависимости от версии mysql и количества данных. Имеет смысл попробовать переписать в join.

Второй:
зачем вообще внешний селект? Зачем группировка, сортировка и чуть менее чем все джойны?

Апдейты очевидно ждут блокировки. Если у вас единственно вменяемый innodb (и изоляция транзакций не serializable) - то селект их заблокировать не мог, блокирует кто-то другой.
Если какой-нибудь myisam - то разумеется все они дерутся за табличную блокировку.


-----
PostgreSQL DBA
 
 Top
x-miller-x
Отправлено: 26 Апреля, 2017 - 11:16:04
Post Id


Новичок


Покинул форум
Сообщений всего: 52
Дата рег-ции: Апр. 2012  


Помог: 0 раз(а)




1. distinct уберу, а джойны просто нужны еще когда надо делать выборку по полям этих таблицы

переписал subquery в Join

CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. SELECT count(DISTINCT product.id)
  3.     FROM `product`
  4.     JOIN `product_to_city` ON `product`.`publish` = 1
  5.         AND `product`.`archive` != 1 AND `product`.`delete` != 1
  6.         AND `product_to_city`.`product_id` = `product`.`id`
  7.     JOIN `city` AS `c` ON (`c`.`id` = 104 OR `c`.`parent_id` = 104)
  8.         AND `c`.`id` = `product_to_city`.`city_id`
  9.     JOIN `city` ON `city`.`id` = `product`.`city_id`
  10.     JOIN `company` ON `company`.`id` = `product`.`company_id`
  11.  


2. group нужен для того чтобы группировать по product.id так как при обычной выборке без group туда попадают дубли, соотвественно когда count внутри этого запроса то получаем несколько строк с количеством товаров у этого тега, поэтому пришлось написать внешний count чтобы считать общее количество записей


3. Насчет MyIsam там только одна таблица MyIsam и то не участвует в выборке, только записываю данные, думаете он блокирует?
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« SQL и Архитектура БД »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB