簡體   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