SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 15.10.2013 00:47:23

VictorK
Участник
Зарегистрирован: 15.10.2013
Сообщений: 9

Нужна помощь по оптимизации запроса

У меня магазин на Opencart 1.5.4.1
На локальном сервере нашел медленный запрос:

# Time: 131013 18:59:57
# User@Host: root[root] @ localhost [127.0.0.1]
# Query_time: 11.390625  Lock_time: 0.000000 Rows_sent: 10  Rows_examined: 4413
use magazin;
SET timestamp=1381683597;
SELECT p.product_id, (SELECT AVG(rating) AS total FROM review r1 WHERE r1.product_id = p.product_id AND r1.status = '1' GROUP BY r1.product_id) AS rating FROM product p LEFT JOIN product_description pd ON (p.product_id = pd.product_id) LEFT JOIN product_to_store p2s ON (p.product_id = p2s.product_id) LEFT JOIN product_to_category p2c ON (p.product_id = p2c.product_id) WHERE pd.language_id = '1' AND p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '0' AND p2c.category_id = '20' GROUP BY p.product_id ORDER BY p.quantity DESC, LCASE(pd.name) DESC LIMIT 0,10;

Я не специалист в этом вообще.
Кто может помочь в этом.
Сайт действующий, но периодически падает - 503 ошибка.
Времени читать документацию нет.
Буду рад любой толковой помощи.
Если предоставил мало информации, то могу чего-нбудь добавить по запросу.

Неактивен

 

#2 15.10.2013 02:01:58

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Нужна помощь по оптимизации запроса

Покажите результат
explain ваш запрос;
и структуру всех входящих в него таблиц, т.е.
show create table product;
и т.д.

Неактивен

 

#3 15.10.2013 09:28:27

VictorK
Участник
Зарегистрирован: 15.10.2013
Сообщений: 9

Re: Нужна помощь по оптимизации запроса

id     select_type     table     type     possible_keys     key     key_len     ref     rows     Extra
1     PRIMARY     p2s     index     PRIMARY     PRIMARY     8     NULL    1323     Using where; Using index; Using temporary; Using filesort
1     PRIMARY     pd     eq_ref     PRIMARY     PRIMARY     8     cdroom_mail_ru_.p2s.product_id,const     1     Using where
1     PRIMARY     p     eq_ref     product_id     product_id     4     cdroom_mail_ru_.p2s.product_id     1     Using where
1     PRIMARY     p2c     eq_ref     PRIMARY     PRIMARY     8     cdroom_mail_ru_.p.product_id,const     1     Using where; Using index
2     DEPENDENT SUBQUERY     NULL    NULL    NULL    NULL    NULL    NULL    NULL    Impossible WHERE noticed after reading const tables



Table     Create Table
product     CREATE TABLE `product` (
`product_id` int(11) NO...


Можно было фоткой выложить, но я не понял как это здесь сделать.

Неактивен

 

#4 15.10.2013 09:36:07

VictorK
Участник
Зарегистрирован: 15.10.2013
Сообщений: 9

Re: Нужна помощь по оптимизации запроса

Вторая часть более полная


product     CREATE TABLE `product` (
`product_id` int(11) NOT NULL AUTO_INCREMENT,
`model` varchar(64) NOT NULL,
`sku` varchar(64) NOT NULL,
`upc` varchar(12) NOT NULL,
`ean` varchar(14) NOT NULL,
`jan` varchar(13) NOT NULL,
`isbn` varchar(13) NOT NULL,
`mpn` varchar(64) NOT NULL,
`location` varchar(128) NOT NULL,
`quantity` int(4) NOT NULL DEFAULT '0',
`stock_status_id` int(11) NOT NULL,
`image` varchar(255) DEFAULT NULL,
`manufacturer_id` int(11) NOT NULL,
`shipping` tinyint(1) NOT NULL DEFAULT '1',
`price` decimal(15,4) NOT NULL DEFAULT '0.0000',
`points` int(8) NOT NULL DEFAULT '0',
`tax_class_id` int(11) NOT NULL,
`date_available` date NOT NULL,
`weight` decimal(15,8) NOT NULL DEFAULT '0.00000000',
`weight_class_id` int(11) NOT NULL DEFAULT '0',
`length` decimal(15,8) NOT NULL DEFAULT '0.00000000',
`width` decimal(15,8) NOT NULL DEFAULT '0.00000000',
`height` decimal(15,8) NOT NULL DEFAULT '0.00000000',
`length_class_id` int(11) NOT NULL DEFAULT '0',
`subtract` tinyint(1) NOT NULL DEFAULT '1',
`minimum` int(11) NOT NULL DEFAULT '1',
`sort_order` int(11) NOT NULL DEFAULT '0',
`status` tinyint(1) NOT NULL DEFAULT '0',
`date_added` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`date_modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`viewed` int(5) NOT NULL DEFAULT '0',
UNIQUE KEY `product_id` (`product_id`)
) ENGINE=MyISAM AUTO_INCREMENT=1401 DEFAULT CHARSET=utf8

Неактивен

 

#5 15.10.2013 13:42:16

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Нужна помощь по оптимизации запроса

А ещё покажите так же структуру остальных таблиц (фоткой лучше не надо).
product_description
product_to_store
product_to_category
review

Неактивен

 

#6 15.10.2013 14:04:24

VictorK
Участник
Зарегистрирован: 15.10.2013
Сообщений: 9

Re: Нужна помощь по оптимизации запроса

Table     Create Table
product_description     CREATE TABLE `product_description` (
`product_id` int(11) NOT NULL AUTO_INCREMENT,
`language_id` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
`description` text NOT NULL,
`meta_description` varchar(255) NOT NULL,
`meta_keyword` varchar(255) NOT NULL,
`seo_title` varchar(255) NOT NULL,
`seo_h1` varchar(255) NOT NULL,
`tag` text NOT NULL,
PRIMARY KEY (`product_id`,`language_id`)
) ENGINE=MyISAM AUTO_INCREMENT=1401 DEFAULT CHARSET=utf8


Table     Create Table
product_to_store     CREATE TABLE `product_to_store` (
`product_id` int(11) NOT NULL,
`store_id` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`product_id`,`store_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8


Table     Create Table
product_to_category     CREATE TABLE `product_to_category` (
`product_id` int(11) NOT NULL,
`category_id` int(11) NOT NULL,
`main_category` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`product_id`,`category_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8


Table     Create Table
review     CREATE TABLE `review` (
`review_id` int(11) NOT NULL AUTO_INCREMENT,
`product_id` int(11) NOT NULL,
`customer_id` int(11) NOT NULL,
`author` varchar(64) NOT NULL DEFAULT '',
`text` text NOT NULL,
`rating` int(1) NOT NULL,
`status` tinyint(1) NOT NULL DEFAULT '0',
`date_added` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`date_modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`review_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

Неактивен

 

#7 15.10.2013 14:39:01

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Нужна помощь по оптимизации запроса

А этот запрос всегда выполняется долго или это разовое попадание в лог медленных?

Из того что можно предложить по самому запросу:
1. заменить все left join на join
2. разбить запрос на 2
сначала найти 10 нужных product_id (т.е. ваш запрос без подзапроса, который считает рейтинг). Затем отдельно посчитать рейтинг для 10 нужных product_id

Неактивен

 

#8 15.10.2013 17:23:44

VictorK
Участник
Зарегистрирован: 15.10.2013
Сообщений: 9

Re: Нужна помощь по оптимизации запроса

Честно говоря я даже не знаю куда и как прописывать эти запросы, чтоб они постоянно там обрабатывались.
По поводу всегда или нет не знаю, но думаю, что и из-за него  тоже, т.к. страница может загрузиться за 10 сек, а может и за 20-25, это то что я первое пока нашел.
На странице 15 фоток товара, кнопка купить,быстрый показ, цена.
Еще через firebug смотрел загрузку страницы продуктов.
Вот 2 медленные:
Это я так понял переход на страницу товаров категории в начале, длится 8-9 секунд (Get index...).

Заголовки ответапоказать исходный код
Cache-Control    no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection    Keep-Alive
Content-Type    text/html; charset=windows-1251
Date    Tue, 15 Oct 2013 14:15:26 GMT
Expires    Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive    timeout=5, max=94
Pragma    no-cache
Server    Apache/2.2.22 (Win32) mod_ssl/2.2.22 OpenSSL/1.0.1c PHP/5.3.13
Transfer-Encoding    chunked
X-Powered-By    PHP/5.3.13
Заголовки запросапоказать исходный код
Accept    text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding    gzip, deflate
Accept-Language    ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Connection    keep-alive
Cookie    vc=4; language=ru; currency=RUB; __gads=ID=9571e3a080b8ab8c:T=1381831191:S=ALNI_MaIUTuBf8fyRHxwfS2COJtbkGXRNA; PHPSESSID=4obecn67vupplj7e5k3mk1gap5
Host    localhost
Referer    http://localhost/magazin/
User-Agent    Mozilla/5.0 (Windows NT 5.1; rv:24.0) Gecko/20100101 Firefox/24.0

И в конце закрывается 9 секунд:

Заголовки ответапоказать исходный код
Cache-Control    no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection    Keep-Alive
Content-Type    text/html; charset=windows-1251
Date    Tue, 15 Oct 2013 14:15:40 GMT
Expires    Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive    timeout=5, max=90
Pragma    no-cache
Server    Apache/2.2.22 (Win32) mod_ssl/2.2.22 OpenSSL/1.0.1c PHP/5.3.13
Transfer-Encoding    chunked
X-Powered-By    PHP/5.3.13
Заголовки запросапоказать исходный код
Accept    image/png,image/*;q=0.8,*/*;q=0.5
Accept-Encoding    gzip, deflate
Accept-Language    ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Connection    keep-alive
Cookie    vc=4; language=ru; currency=RUB; __gads=ID=9571e3a080b8ab8c:T=1381831191:S=ALNI_MaIUTuBf8fyRHxwfS2COJtbkGXRNA; PHPSESSID=4obecn67vupplj7e5k3mk1gap5
Host    localhost
Referer    http://localhost/magazin/index.php?route=product/category&path=20
User-Agent    Mozilla/5.0 (Windows NT 5.1; rv:24.0) Gecko/20100101 Firefox/24.0

Неактивен

 

#9 15.10.2013 17:32:01

VictorK
Участник
Зарегистрирован: 15.10.2013
Сообщений: 9

Re: Нужна помощь по оптимизации запроса

Есть еще один медленный запрос:

# Time: 131013 19:42:22
# User@Host: root[root] @ localhost [127.0.0.1]
# Query_time: 6.625000  Lock_time: 0.000000 Rows_sent: 111  Rows_examined: 111
SET timestamp=1381686142;
SHOW TABLE STATUS FROM `magazin`;

Неактивен

 

#10 15.10.2013 19:42:33

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Нужна помощь по оптимизации запроса

Если вы в клиенте mysql выполните ваш медленный запрос (SELECT p.product_id, (SELECT AVG(rating) ...) сколько он будет выполняться?
И какая у вас версия сервера MySQL, что показывает команда select version();

Неактивен

 

#11 15.10.2013 20:11:57

VictorK
Участник
Зарегистрирован: 15.10.2013
Сообщений: 9

Re: Нужна помощь по оптимизации запроса

0.03-0.045с , но бывает и 0.8-2 с (%10).
5.5.25

Неактивен

 

#12 16.10.2013 11:41:34

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Нужна помощь по оптимизации запроса

Т.е. у вас не сам запрос медленный, а медленный из-за внешних причин. Нужно искать узкие места, см., например, ботанический определитель узких мест.

И ещё покажите show global variables; и show global status;

Неактивен

 

#13 17.10.2013 09:08:37

VictorK
Участник
Зарегистрирован: 15.10.2013
Сообщений: 9

Re: Нужна помощь по оптимизации запроса

2 медленных запроса я убрал в CDN - jquery.js
Стало немного лучше.
Мой хостер посоветовал мне изменить на это.
Единственное, я не знаю как и куда это записывать, чтобы обрабатывалось постоянно.
Могли бы Вы мне пошагово объяснить как это сделать, и чтоб старый запрос не выполнялся?


SELECT

        p.product_id,
 
        AVG(rating) AS total

FROM product p

        LEFT JOIN product_description pd ON (p.product_id = pd.product_id)
 
        LEFT JOIN product_to_store p2s ON (p.product_id = p2s.product_id)

        LEFT JOIN product_to_category p2c ON (p.product_id = p2c.product_id)
 
        LEFT JOIN review r1 ON (p.product_id = r1.product_id AND r1.status = '1')

WHERE

        pd.language_id = '1' AND
 
        p.status = '1' AND

        p.date_available <= NOW() AND

        p2s.store_id = '0' AND
 
        p2c.category_id = '20'

GROUP BY p.product_id, r1.rating

ORDER BY p.quantity DESC, LCASE(pd.name) DESC LIMIT 0,10;

Он будет работать быстрее предыдущего запроса с вложенным SELECT.


Кроме того, мы бы посоветовали вынести значение NOW() в какую-либо переменную, объявленную до выполнения запроса. В этом случае вызов функции будет сделан один раз, а не каждый раз при сравнении строк (при проверке критериев в конструкции WHERE).

Также, в общем случае следует избегать выполнения сортировки на уровне базы данных - лучше выполнять ее на уровне вызывающего кода. Поэтому строку:

ORDER BY p.quantity DESC, LCASE(pd.name) DESC LIMIT 0,10;

лучше из запроса убрать, а соответствующую выборку делать на уровне бизнес-логики. В случае, если результирующее количество данных велико, то тогда сортировку нужно делать на уровне БД, при этом необходимо настраивать использование индексов, чтобы выборка происходила быстрее.

Скорость выполнения указанных рекомендаций следует проверять на реальных данных, замеряя каждый раз полученные результаты, поскольку каждый сервер баз данных по-разному оптимизирует схему выполнения запросов.

Неактивен

 

#14 17.10.2013 14:23:18

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Нужна помощь по оптимизации запроса

VictorK написал:

Единственное, я не знаю как и куда это записывать, чтобы обрабатывалось постоянно.
Могли бы Вы мне пошагово объяснить как это сделать, и чтоб старый запрос не выполнялся?

Изменения нужно вносить в скрипты, которые формируют этот запрос.

VictorK написал:

Он будет работать быстрее предыдущего запроса с вложенным SELECT.

Не факт.

VictorK написал:

Кроме того, мы бы посоветовали вынести значение NOW() в какую-либо переменную, объявленную до выполнения запроса. В этом случае вызов функции будет сделан один раз, а не каждый раз при сравнении строк (при проверке критериев в конструкции WHERE).

Можно, но это уже нюансы.


VictorK написал:

Также, в общем случае следует избегать выполнения сортировки на уровне базы данных - лучше выполнять ее на уровне вызывающего кода.

Сомнительное утверждение.


VictorK написал:

Поэтому строку:

ORDER BY p.quantity DESC, LCASE(pd.name) DESC LIMIT 0,10;

лучше из запроса убрать, а соответствующую выборку делать на уровне бизнес-логики. В случае, если результирующее количество данных велико, то тогда сортировку нужно делать на уровне БД, при этом необходимо настраивать использование индексов, чтобы выборка происходила быстрее.

У вас как раз случай - результирующее количество данных велико.

VictorK написал:

Скорость выполнения указанных рекомендаций следует проверять на реальных данных, замеряя каждый раз полученные результаты, поскольку каждый сервер баз данных по-разному оптимизирует схему выполнения запросов.

Верное замечание.

Улучшение конкретного запроса дело хорошее, но узкое место, судя по приведенным вами данным о времени выполнения запроса вручную, не в нем.
Что же касается исправления самого запроса, то рекомендации из моего 7го поста остаются в силе.

P.S. А что у вас за хостинг?

Неактивен

 

#15 17.10.2013 15:23:31

VictorK
Участник
Зарегистрирован: 15.10.2013
Сообщений: 9

Re: Нужна помощь по оптимизации запроса

Изменения нужно вносить в скрипты, которые формируют этот запрос.
А вот это можно подробней?

Хостинг белорусский - HB.BY, у нас по закону зарубежный нельзя.
У меня в принципе быстро грузится страница, основное время занимает "первый байт" -от 2 сек и до 8-10 сек.
И в конце Get "мой сайт" тоже пару секунд.
Я так понял чтоб уменьшить кол-во 503 ошибки необходимо уменьшить кол-во запросов к серверу, а не трогать запросы.
У меня виртуальный хостинг, нагрузка не велика, о обращений к первой странице 114-117, тестил спомощью http://www.webpagetest.org.

Неактивен

 

#16 17.10.2013 16:36:34

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Нужна помощь по оптимизации запроса

VictorK написал:

Изменения нужно вносить в скрипты, которые формируют этот запрос.
А вот это можно подробней?

А как? Подробней только сделать.

VictorK написал:

Хостинг белорусский - HB.BY, у нас по закону зарубежный нельзя.

Сурово у вас smile

VictorK написал:

Я так понял чтоб уменьшить кол-во 503 ошибки необходимо уменьшить кол-во запросов к серверу, а не трогать запросы.

Нет. http://www.jino.ru/support/faq/problems … #error-503

Давайте определимся о чем идет речь. Я правильно понимаю,что:
1) у вас на хостинге запущен slow-query-log
2) в нем медленный запрос (11 сек), который вы процитировали в первом посте (в логе этот запрос встречается часто или нет)
3) если вы выполняете этот запрос в ручную, то он выполняется быстро (выполняете естественно на сервере)

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson