繁体   English   中英

MySQL的JOIN与SUBQUERY非常慢

[英]MySQL JOIN with SUBQUERY very slow

我有一个论坛,我想查看作者姓名和最近一次回答的用户的最新话题

表格主题(论坛)

| idTopic | IdParent | User | Title | Text             |
--------------------------------------------------------
| 1       | 0        | Max  | Help! | i need somebody  | 
--------------------------------------------------------
| 2       | 1        | Leo  |       | What?!           |  

查询:

SELECT 
    Question.*,
    Response.User AS LastResponseUser 
FROM Topic AS Question
LEFT JOIN (
   SELECT User, IdParent  
   FROM Topic 
   ORDER BY idTopic DESC
) AS Response 
    ON ( Response.IdParent = Question.idTopic )
WHERE Question.IdParent = 0
GROUP BY Question.idTopic
ORDER BY Question.idTopic DESC

输出:

| idTopic | IdParent | User | Title | Text             | LastResponseUser |
---------------------------------------------------------------------------
| 1       | 0        | Max  | Help! | i need somebody  | Leo              |
---------------------------------------------------------------------------

示例: http//sqlfiddle.com/#!2 / 22f72 / 4

该查询有效,但是非常慢(在25,000条记录上大约0.90秒)。

我怎样才能使其更快?

更新

拟议解决方案之间的比较

http://sqlfiddle.com/#!2/94068/22

假设最高IDTopic是最后一个响应用户...并假设您想返回没有响应的主题...

Select A.IDTopic, A.IDParent, A.User, A.Title, A.Text, 
case when b.User is null then 'No Response' else B.User end as LastReponseUser
FROM topic A
LEFT JOIN Topic B
 on A.IdTopic = B.IDParent
 and B.IDTopic = (Select max(IDTopic) from Topic 
                  where IDParent=B.IDParent group by IDParent)
WHERE  A.IDParent =0

如果使用当前架构,建议添加索引(尤其是聚集索引(主键))并简化SQL,以便让mySQL进行优化语句的工作,而不是强制其运行子查询,对结果进行排序,然后运行主查询。

CREATE TABLE Topic (
  idTopic  INT
  ,IdParent INT
  ,User     VARCHAR(100)
  ,Title    VARCHAR(255)
  ,Text     VARCHAR(255)       
  ,CONSTRAINT Topic_PK PRIMARY KEY (idTopic) 
  ,CONSTRAINT Topic_idTopic_UK UNIQUE (idTopic) 
  ,INDEX Topic_idParentIdTopic_IX (idParent, idTopic)
);


INSERT INTO Topic (idTopic, IdParent, User, Title, Text) VALUES 
(1, 0, 'Max', 'Help!', 'i need somebody'),
(2, 1, 'Leo', '', 'What!?');


SELECT Question.*
, Response.User AS LastResponseUser 
FROM Topic AS Question
LEFT JOIN Topic AS Response 
  ON Response.IdParent = Question.idTopic
WHERE Question.IdParent = 0
order by Question.idTopic
;

http://sqlfiddle.com/#!2/7f1bc/1

更新资料

在您提到的评论中,您只需要最新的回复。 为此,请尝试以下操作:

SELECT Question.*
, Response.User AS LastResponseUser 
FROM Topic AS Question
LEFT JOIN (
  select a.user, a.idParent 
  from Topic as a
  left join Topic as b
  on b.idParent = a.idParent
  and b.idTopic > a.idTopic
  where b.idTopic is null 
) AS Response 
  ON Response.IdParent = Question.idTopic
WHERE Question.IdParent = 0
order by Question.idTopic
;

http://sqlfiddle.com/#!2/7f1bc/3

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM