这个查询有点慢,我想优化它,任何想法?
SELECT DISTINCT a.id
FROM article a
LEFT JOIN article_comment ac
ON a.id = ac.article_id
LEFT JOIN comment c
ON ac.id = c.id
WHERE a.id IN (SELECT a2.id
FROM article_user_read aur
LEFT JOIN article a2
ON aur.article_id = a2.id
WHERE c.published_date > aur.read_date
AND aur.user_id = 36748
AND aur.followed = 1)
ORDER BY c.published_date DESC
这是article_user_read表:
CREATE TABLE `article_user_read` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`article_id` int(11) DEFAULT NULL,
`user_id` int(11) DEFAULT NULL,
`read_date` datetime NOT NULL,
`followed` tinyint(1) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UNIQ_BBE52A0262922701A76ED395` (`article_id`,`user_id`),
KEY `IDX_BBE52A0262922701` (`article_id`),
KEY `IDX_BBE52A02A76ED395` (`user_id`),
CONSTRAINT `article_user_read_ibfk_3` FOREIGN KEY (`article_id`) REFERENCES `article` (`id`),
CONSTRAINT `article_user_read_ibfk_4` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=20193 DEFAULT CHARSET=latin1;
另一个只是简单的文章&用户表。
答案 0 :(得分:1)
SELECT DISTINCT a.id
FROM article AS a
JOIN article_user_read AS aur
ON aur.article_id = a.id
JOIN comment AS c
ON ac.id = c.id
JOIN article_comment AS ac
ON a.id = ac.article_id
WHERE c.published_date > aur.read_date
AND aur.user_id = 36748
AND aur.followed = 1
ORDER BY c.published_date DESC
LEFT JOIN
article_user_read
与article
无关,因为您对文章感兴趣,所以您不关心是否有没有article_user_read关系的文章 - - 可以优化为JOIN
。
您还只想要在用户阅读文章后发表评论的文章,因此article
,article_comment
和comment
之间的关系必须存在 - 可以优化为{ {1}}秒。
然而,主要的变化是您不需要相关的子查询(在子查询中引用评论JOIN
),因此c
和JOIN
之间的article_user_read
{1}}可以推送到主查询。
答案 1 :(得分:0)
一个疯狂的猜测:将“IN”替换为“WHERE EXISTS”通常会得到回报:
SELECT DISTINCT a.id
FROM article a
LEFT JOIN article_comment ac
ON a.id = ac.article_id
LEFT JOIN comment c
ON ac.id = c.id
WHERE EXISTS (
SELECT *
FROM article_user_read aur
LEFT JOIN article a2
ON aur.article_id = a2.id
WHERE c.published_date > aur.read_date
AND aur.user_id = 36748
AND aur.followed = 1
AND a.id = a2.id
)
ORDER BY c.published_date DESC
答案 2 :(得分:0)
鉴于您只对此查询中的文章ID感兴趣,因此可以将其简化为:
SELECT a.id
FROM article a
WHERE EXISTS
(SELECT NULL
FROM article_comment ac
INNER JOIN comment c ON ac.id = c.id
INNER JOIN article_user_read aur
ON aur.article_id = a.id AND c.published_date > aur.read_date
WHERE a.id = ac.article_id AND
aur.user_id = 36748 AND
aur.followed = 1)
答案 3 :(得分:0)
由于您只关注不同的ID,我只会从article_user_read表中预先查询,因为这是您的WHERE EXISTS的完整基础,然后链接到文章并拉出您想要的任何其他列...此外,您正在进行LEFT JOIN,但最终需要根据“c.published_date”的相应WHERE子句进行查找,这意味着所有条目都需要一直到注释表。所以LEFT JOIN不适用......我唯一要做的就是在用户ID和Followed标志上为article_user_read表添加一个索引。
SELECT distinct
aur.article_id
from
article_user_read aur
join article a
on aur.article_id = a.id
join article_comment ac
on aur.article_id = ac.article_id
join comment c
on ac.id = c.id
and c.published_date > aur.read_date
where
aur.user_id = 36748
and aur.followed = 1