这是我的mysql查询(3个嵌套的Select语句):
SELECT * FROM emotions
WHERE
( randomid IN
(
SELECT idpost
FROM p_n_relation
WHERE idnetwork IN
(
SELECT id
FROM networks
WHERE name = 'Babblenow'
AND isActive = 1
AND isDeleted = 0
)
AND isActive = 1 AND isDeleted = 0
) AND isActive = 1
AND isDeleted =0
AND onid = '0' AND type = 0
)ORDER BY rating DESC
每个表格情感,p_n_relations和网络包含大约10k行。
执行此查询需要30秒以上的时间并在服务器运行时挂起服务器!
有没有更有效的方法来做我想做的事情?大公司如何在几秒钟内完成这项工作?
编辑 -
要完全:
p_n_relations : 5774
,networks : 9
,emotions : 427
中的行数
这是Query took 125.6770 sec
。
我的数据库结构:
情绪表,网络表,P_n_relation表按顺序排列。
http://imgur.com/bmEEavH,d3iE6Lg,twXMWU9
答案 0 :(得分:3)
试试这个:
SELECT emotions.* FROM emotions
LEFT JOIN p_n_relation ON (p_n_relation.idpost = emotions.randomid)
LEFT JOIN networks ON (networks.id = p_n_relation.idnetwork)
WHERE
(networks.name='Babblenow') AND (networks.isActive = 1) AND (networks.isDeleted = 0) AND
(p_n_relation.isActive = 1) AND (p_n_relation.isDeleted = 0) AND
(emotions.isActive = 1) AND (emotions.isDeleted = 0) AND (emotions.onid = '0') AND (emotions.type = 0)
ORDER BY emotions.rating DESC
根据您发布的表格结构,我建议对emotion.randomid和p_n_relation.idpost(现在为varchar(40)和varchar(50))使用相同的字段类型。除此之外,还有关于emotion.randomid,p_n_relation.idpost,networks.id和p_n_relation.idnetwork的指示。正如其他人建议尝试在networks.name上制作索引。之后,尝试逐步构建查询。
首先,从情绪中选择情绪。但不要在哪里使用并测量时间。它应该很快,如果不是你的MySQL配置有一些很大的问题。
SELECT emotions.* FROM emotions;
如果它很快,请加入p_n_relation,但不要使用where。
SELECT emotions.*, p_n_relation.* FROM emotions
LEFT JOIN p_n_relation ON (p_n_relation.idpost = emotions.randomid);
如果你有正确的索引,它也应该快。如果没有,请尝试解析它:
EXPLAIN SELECT emotions.*, p_n_relation.* FROM emotions
LEFT JOIN p_n_relation ON (p_n_relation.idpost = emotions.randomid);
您可以阅读有关EXPLAIN输出的here,但您也可以将其发布到您的问题中。
因此,如果它仍然很快,请加入第3个表格:
SELECT emotions.*, p_n_relation.* FROM emotions
LEFT JOIN p_n_relation ON (p_n_relation.idpost = emotions.randomid)
LEFT JOIN networks ON (networks.id = p_n_relation.idnetwork);
测试,测量,然后开始逐步包含WHERE部分。如果某个地方性能下降,你应该调查它(可能是一个错误的或缺少的索引,字段类型,或MySQL本身可能导致问题)。
答案 1 :(得分:0)
转换为连接,反转连接顺序:
SELECT DISTINCT e.*
FROM networks n
JOIN p_n_relation r ON r.idnetwork = n.id
JOIN emotions e ON e.randomid = r.idpost
WHERE n.name = 'Babblenow'
AND n.isActive = 1
AND n.isDeleted = 0
此表顺序是最佳的,因为您的条件都在网络表上。优化器假定来识别它并自动更改连接顺序,但我通过经验发现优化器可能很密集。
创建索引(如果它们尚不存在):
create index networks_name on networks(name);
create index p_n_relation_idnetwork on (p_n_relation(idnetwork);