有没有办法优化以下MySql查询?
SELECT article.*
FROM article
WHERE channelid = 1
AND ((SELECT count(*) FROM article_cCountry WHERE ID1 = article.id AND ID2 = 1) = 1)
AND date < now()
AND released = "TRUE"
AND ( (uId = 0) OR ((SELECT count(*) FROM user WHERE ID = article.uId and released = true) = 1) )
ORDER BY cDate DESC
LIMIT 20
我已经尝试使用INNER JOIN进行article_cCountry检查,但性能更差。
修改
article_cCountry的结构
| ID | ID1 | ID2 | (ID1 => article.id, ID2 => country)
用户用户的结构
包含用户数据的约20列
答案 0 :(得分:1)
我不确定你需要检查
SELECT article.*, COUNT(ac.id) ac_count, COUNT(u.id) u_count
FROM article
INNER JOIN article_cCountry ac ON ac.ID1 = article.id AND ac.ID2 = 1
INNER JOIN user u ON u.ID = article.uId and u.released
WHERE
channelid = 1
AND date < now()
AND released = "TRUE"
GROUP BY article.id
HAVING ac_count = 1 AND (uId = 0 OR u_count = 1)
ORDER BY cDate DESC
LIMIT 20
答案 1 :(得分:0)
尝试使用以下方法解释您的查询:
EXPLAIN SELECT ...
如果您没有使用任何索引,请尝试在where:
中使用的字段上添加索引article.date
article.channelid
article.released
user.released
article_cCountry.id1
article_cCountry.id2
答案 2 :(得分:0)
试试这个:
选择 文章。* 从 文章 INNER JOIN article_cCountry ON article.id = article_cCountry.ID1 INNER JOIN
USER
ON article.uId =USER
。身份证 WHERE channelid = 1 AND article_cCountry.ID2 = 1 ANDUSER
。已发布= TRUE 和日期&lt;现在() AND release = TRUE 订购cDate DESC 限制20;
答案 3 :(得分:0)
尝试将子查询放入临时表
CREATE TEMPORARY TABLE COUNTRY
(
countryCount INT,
articleId INT
)
INSERT INTO
COUNTRY
SELECT
COUNT(1),
ID1,
FROM
article_cCountry
WHERE
ID2 = 1
GROUP BY
ID1
CREATE TEMPORARY TABLE USERS
(
userCount INT,
articleId INT
)
INSERT INTO
USERS
SELECT
COUNT(1),
ID
FROM
[user]
WHERE
released = true
GROUP BY
ID
SELECT
article.*
FROM
article JOIN COUNTRY country ON country.articleId = article.id
JOIN USERS users ON users.articleId = article.uId
WHERE
channelid = 1
AND
--((SELECT count(*) FROM article_cCountry WHERE ID1 = article.id AND ID2 = 1) = 1)
country.countryCount = 1
AND
date < now()
AND
released = "TRUE"
AND
(
(uId = 0)
OR
--((SELECT count(*) FROM user WHERE ID = article.uId and released = true) = 1))
(users.userCount = 1)
)
ORDER BY
cDate DESC
LIMIT 20
DROP TABLE COUNTRY;
DROP TABLE USERS;