我有这个选择:
select 'like' prefix
, l.post
, l.data as data
, l.user
, concat(k.user, ' liked you') as logs
from likes l
inner join posts p on l.post = p.id
inner join cadastro k on l.user = k.id
where p.user = 1 and l.user <> p.user
order by data desc
limit 10
花了2.3993秒。
`likes` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`user` int(11) UNSIGNED NOT NULL,
`post` int(11) UNSIGNED NOT NULL,
`data` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `user_post` (`user`,`post`),
KEY `post_user` (post, user),
FOREIGN KEY (`user`) REFERENCES cadastro (`id`),
FOREIGN KEY (`post`) REFERENCES posts (`id`) ON DELETE CASCADE
)
`posts` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`cadastro` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
任何提高速度的想法?我也尝试在喜欢数据上添加索引,但没有注意到差异。
答案 0 :(得分:3)
这是您的查询:
select 'like' as prefix, l.post, l.data as data, l.user,
concat(k.user, ' liked you') as logs
from likes l join
posts p
on l.post = p.id oin
cadastro k
on l.user = k.id
where p.user = 1 and l.user <> p.user
order by data desc
limit 10;
对于此查询,您需要post(user, id)
,likes(post, user, data)
和cadastro(id, user)
上的索引。
您无法消除order by
的开销,但这会加快查询的连接和过滤部分。
答案 1 :(得分:1)
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
。
警告:如果没有人喜欢你,结果集可能与此查询不同。如果这是一个问题,我会重新制定它以使用“衍生的”#39;表
通过将cadastro查找移动到子查询中,我认为行动发生的频率低于cadastro在JOIN
中的情况。这不是通用优化 - 请注意WHERE
子句很复杂,因为它涉及多个表。我不清楚p
上的索引是否会完全通过data
,并且对LIMIT
提供帮助。如需进一步调查,请提供EXPLAIN FORMAT=JSON SELECT ...