Прошу помочь оптимизировать запрос и/или табличку MySQL

12
Asar
На сайте с 23.08.2004
Offline
328
1232

Запрос дергает последние комменты из каждой темы (отдельно для тем про фото, про объекты в каталоге и про новости):

SELECT *
FROM Comments s1
WHERE
DaTime=(SELECT MAX(s2.DaTime)
FROM Comments s2
WHERE Ctype = 2 AND s1.Photo_Id = s2.Photo_Id)
OR DaTime=(SELECT MAX(s3.DaTime)
FROM Comments s3
WHERE Ctype = 1 AND s1.Object_Id = s3.Object_Id)
OR DaTime=(SELECT MAX(s4.DaTime)
FROM Comments s4
WHERE (Ctype = 0 OR Ctype = 3 OR Ctype = 4) AND s1.Topic_Id = s4.Topic_Id AND Topic_Id != 181)
ORDER BY DaTime DESC LIMIT 50

Все более-менее нормально ворочается до тех пор, пока не проставляю дополнительное условие — чтобы поле Comment1 не было бы пустым:

SELECT *
FROM Comments s1
WHERE
DaTime=(SELECT MAX(s2.DaTime)
FROM Comments s2
WHERE Ctype = 2 AND s1.Photo_Id = s2.Photo_Id AND Comment1 != '')
OR DaTime=(SELECT MAX(s3.DaTime)
FROM Comments s3
WHERE Ctype = 1 AND s1.Object_Id = s3.Object_Id AND Comment1 != '')
OR DaTime=(SELECT MAX(s4.DaTime)
FROM Comments s4
WHERE (Ctype = 0 OR Ctype = 3 OR Ctype = 4) AND s1.Topic_Id = s4.Topic_Id AND Topic_Id != 181 AND Comment1 != '')
ORDER BY DaTime DESC LIMIT 50

После чего наступает адов ад — или вывод данных идет крайне долго, или вообще не успевает и вываливается в 504.

Поле Comment1 — text, без отдельных ограничений по размеру. Количество строк в таблице — порядка 6000. Хостинг — обычный виртуальный.

Граждане, можно тут чего-нить соптимизировать или только на бОльшие мощи переехать?..

З.Ы. Причем если проставить условие AND Comment != '' вместо AND Comment1 != '', то все бегает гораздо быстрее. Впрочем, между полями есть различие: Comment почти все заполнены, а Comment1 почти все пустые.

S1
На сайте с 13.03.2008
Offline
49
#1

Корректнее будет проверять на пустоту так: Comment1 is not null

Дизайн сайтов (UI/UX), логотипов, баннеров и прочего... (/ru/forum/770062)
[umka]
На сайте с 25.05.2008
Offline
456
#2

Также попробуйте посмотреть, что выдаёт EXPLAIN. Возможно, неправильно определяются индексы при поиске.

Лог в помощь!
Asar
На сайте с 23.08.2004
Offline
328
#3

Спасибо за отзывы. Сегодня проверю и отпишусь дополнительно.

edogs software
На сайте с 15.12.2005
Offline
775
#4

Запрос работает явно с избыточными данными.

Есть острое ощущение, что будет намного быстрее, если Вы сделаете 3 отдельных запроса (в случае если структуру БД нельзя менять).

И однозначно быстрее, если Вы будете хранить метку о том, какой коммент последний и обновлять ее при постинге коммента.

Если непременно хочется одним запросом, посмотрите тут первый вариант.

Разработка крупных и средних проектов. Можно с криптой. Разумные цены. Хорошее качество. Адекватный подход. Продаем lenovo legion в спб, дешевле магазинов, новые, запечатанные. Есть разные. skype: edogssoft
gormarket
На сайте с 29.12.2010
Offline
47
#5

Попробуйте использовать не Comment1, а

s2.Comment1
s3.Comment1
s4.Comment1

Товары и цены в магазинах Вашего города: Городской рынок (http://gormarket.ru/)
Asar
На сайте с 23.08.2004
Offline
328
#6

edogs, спасибо за наводку по поводу метки последнего сообщения. Структура БД вполне поддается редактирования, так что, думаю, реализую такой вариант.

gormarket, спасибо за подсказку, пока метки нет Ваш вариант работает гораздо быстрее, чем было до него.

UP: Блин, рано радовался. добавка s2.Comment1 прироста сокрости не дает, глюканул я...

gormarket
На сайте с 29.12.2010
Offline
47
#7

Asar, уберите из запроса

"AND s1.Photo_Id = s2.Photo_Id"
"AND s1.Object_Id = s3.Object_Id"
"AND s1.Topic_Id = s4.Topic_Id"

потому что при наличии этого условия у Вас находится максимум для каждой строки в таблице s1 и фактически в результирующую выборку попадают все комменты, а не только последние. И хоть какой-то результат Вы получаете только благодаря "ORDER BY DaTime DESC LIMIT 50".

Попробуете сделать Ваш запрос через phpmyadmin и Вы это увидите.

А добавление "AND Comment1 != ''" просто утяжеляет и без того тяжелый запрос!

Asar
На сайте с 23.08.2004
Offline
328
#8

Спасибо всем за комменты. Чуть дописал скрипты, которые обрабатывают новые комменты, обработал все старые комменты, и теперь везде стоят метки у последних комментариев, как и предложил edogs. Теперь все летает. Видать старый вариант запроса и правда чрезмерно загруженный был.

C
На сайте с 20.05.2011
Offline
14
#9
Asar:
Количество строк в таблице — порядка 6000. Хостинг — обычный виртуальный.

отсутствие индексов по полям, которые используются в предикатах ?

Asar
На сайте с 23.08.2004
Offline
328
#10
cryptex:
отсутствие индексов по полям, которые используются в предикатах ?

Ctype, DaTime и Topic_Id/Photo_Id/Object_Id с индексами. Куда уж еще-то?..

12

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