select 'like' prefix ,
l.post ,
l.data as data ,
l.user ,
( SELECT concat(user, ' liked you')
FROM cadastro WHERE id = l.user ) AS logs
from likes l
inner join posts p ON l.post = p.id
where p.user = 1
and l.user <> p.user
order by data desc
limit 10
Индексы:
p: (user, data, id) -- 'covering'; helps WHERE; may help ORDER BY
l: (post)
cadastro: I assume you have PRIMARY KEY(id)
Дальнейшее улучшение: измените индексы likes
с
PRIMARY KEY (`id`),
UNIQUE KEY `user_post` (`user`,`post`),
KEY `post_user` (post, user),
до
PRIMARY KEY(post, user),
INDEX(user, post)
и избавиться от id
.
Предостережение: если никто не понравился вам, результирующий набор может отличаться от этого запроса. Если это проблема, я переформулирую ее, чтобы использовать «производную» таблицу.
Перемещая поиск кадастров в подзапрос, я думаю, что действие происходит реже, чем если бы кадастр находился в JOIN
. Это не универсальная оптимизация - обратите внимание, что предложение WHERE
является сложным, поскольку оно включает в себя более одной таблицы. Мне неясно, будет ли индекс на p
проходить через data
, и поможет ли вообще с LIMIT
. Для дальнейшего расследования, пожалуйста, предоставьте EXPLAIN FORMAT=JSON SELECT ...