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

12
[Удален]
1031

Что лучше? Один большой mysql-запрос с применением нескольких LEFT JOIN или десяток простых запросов?

Пример большого запроса:


SELECT usr_data_template_news_articul.data_template_usrID, usr_data_template_news_articul.list_template_usrID, usr_data_template_news_articul.template_usrID, usr_data_template_news_articul.catalogue_usrID, usr_data_template_news_articul.domain_usrID, usr_data_template_news_articul.profile_usrID, SUBSTRING_INDEX( SUBSTRING_INDEX( usr_data_template_news_articul.name, '[rus]', -1 ) , '[/rus]', 1 ) AS name, SUBSTRING_INDEX( SUBSTRING_INDEX( usr_data_template_news_articul.f_date, '[rus]', -1 ) , '[/rus]', 1 ) AS f_date, SUBSTRING_INDEX( SUBSTRING_INDEX( usr_data_template_news_articul.f_smallimg, '[rus]', -1 ) , '[/rus]', 1 ) AS f_smallimg, SUBSTRING_INDEX( SUBSTRING_INDEX( usr_data_template_news_articul.f_textsmall, '[rus]', -1 ) , '[/rus]', 1 ) AS f_textsmall, SUBSTRING_INDEX( SUBSTRING_INDEX( usr_data_template_news_articul.f_textfull, '[rus]', -1 ) , '[/rus]', 1 ) AS f_textfull, usr_data_template_news_articul.locked, usr_data_template_news_articul.priority, COUNT( usr_data_template_comments.data_template_usrID ) AS cnt_comment, usr_catalogue.url AS url
FROM usr_data_template_news_articul
LEFT JOIN usr_data_template_comments ON usr_data_template_comments.template_usrID = usr_data_template_news_articul.template_usrID
AND usr_data_template_comments.data_usrID = usr_data_template_news_articul.data_template_usrID
LEFT JOIN usr_catalogue ON usr_catalogue.catalogue_usrID = usr_data_template_news_articul.catalogue_usrID
LEFT JOIN usr_rating ON usr_rating.template_usrID = usr_data_template_news_articul.template_usrID
AND usr_rating.data_usrID = usr_data_template_news_articul.data_template_usrID
WHERE usr_data_template_news_articul.domain_usrID =1
AND usr_data_template_news_articul.template_usrID =4
AND usr_data_template_news_articul.catalogue_usrID =8
GROUP BY usr_data_template_news_articul.data_template_usrID
ORDER BY priority DESC
LIMIT 0 , 2

Текущее время выполенения ~0.0176 сек.

L
На сайте с 22.12.2008
Offline
23
#1

Hekcfy, ковыряться в большом запарнее, мне кажется...

Хотя, каждому свое, безусловно.

А по производительности - не скажу, так как большими никогда не пользовался :)

Тиц на выдачу не влияет. Он влияет на размер живота.
[Удален]
#2
letsgo:
ковыряться в большом запарнее, мне кажется..

"ковыряться" в нем не нужно, достаточно один раз написать и радоваться его скорой отработке (к сожалению не в данном случае)

Ufaweb
На сайте с 03.03.2008
Offline
182
#3
Hekcfy:
к сожалению не в данном случа

Дык, отключите кэширование и погоняйте запросы по 1к раз.

Мое мнение: одним запросом лучше. Вопрос в том, как так его составить, чтобы не было лишних движений в субд ☝

Pike
На сайте с 13.07.2004
Offline
79
#4

Я бы наверно поменял

WHERE usr_data_template_news_articul.domain_usrID =1

AND usr_data_template_news_articul.template_usrID =4

AND usr_data_template_news_articul.catalogue_usrID =8

GROUP BY usr_data_template_news_articul.data_template_usrID

на

GROUP BY usr_data_template_news_articul.data_template_usrID

HAVING usr_data_template_news_articul.domain_usrID =1

AND usr_data_template_news_articul.template_usrID =4

AND usr_data_template_news_articul.catalogue_usrID =8

и глянул что получится ;)

free hosting (http://rahost.com)
dlyanachalas
На сайте с 15.09.2006
Offline
693
#5
Pike:
Я бы наверно поменял

WHERE usr_data_template_news_articul.domain_usrID =1
AND usr_data_template_news_articul.template_usrID =4
AND usr_data_template_news_articul.catalogue_usrID =8
GROUP BY usr_data_template_news_articul.data_template_usrID

на

GROUP BY usr_data_template_news_articul.data_template_usrID
HAVING usr_data_template_news_articul.domain_usrID =1
AND usr_data_template_news_articul.template_usrID =4
AND usr_data_template_news_articul.catalogue_usrID =8

и глянул что получится ;)

Так увеличение времени получится, т.к. в первом примере сначала фильтруем, потом группируем, что осталось, а во втором - группируем всё, что есть, а потом фильтруем.

Hekcfy, есть ли индексы ко всем группируемым и сравниваемым полям? Если нет, то надо добавить.

[Удален]
#6

Надо добавить только если поля числовые, и вставка в таблицу не очень часто делается

Вообще я думаю вы в состоянии написать explain + тот же запрос и найти слабые места

[Удален]
#7
dlyanachalas:
Hekcfy, есть ли индексы ко всем группируемым и сравниваемым полям? Если нет, то надо добавить.

Да, индексы есть, связь идет по ним. В explain слабые места я не заметил.

Тут дело все в том, что при выводе списков (для навигации) с помощью этого запроса я экономлю порядка 45 запросов, но на главной странице выполняется аж 6 вот таких больших запросов, а остальных страницах - 1 запрос

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

И все же как будет лучше в плане нагрузки на mysql и быстродействия?

[Удален]
#8
Hekcfy:
с помощью этого запроса я экономлю порядка 45 запросов

Разумеется один запрос лучше 45

Hekcfy:
но на главной странице выполняется аж 6 вот таких больших запросов, а остальных страницах - 1 запрос

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

[Удален]
#9
Hekcfy:
И все же как будет лучше в плане нагрузки на mysql и быстродействия?

Вообще в таких случаях надо проверять просто измерениями.

Но ежу понятно что запросы кешируются и поэтому если у вас на всех страницах один и тот же такой запрос, то нагрузка вряд ли будет значительна, если объем выбираемых данных не очень велик

N
На сайте с 06.05.2007
Offline
419
#10

Покажите уже explain. Чай не база ФСБ.

Если в маркетинговых целях хотите уменьшить число запросов , используйте union.

При желании можно сделать 1 запрос на страничку :)

Вообще, стоимость самого запроса для mysql довольно низкая. Разбивая на мелкие запросы , повышаем вероятность кеширования отдельных частей, тогда как большой запрос тут же исчезнет из кеша, как только изменится хотя бы одна из таблиц.

А ещеее большой join, приводит к повышенному времени на оптимизацию запроса, тк mysql перебирает комбинации планов в поисках наилучшей.

Как тут уже сказали, ничего не бывает лучше полноценного нагрузочного тестирования всего стека приложения.

Кнопка вызова админа ()
12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий