2011-10-10 6 views
0

내가 최신 기사 (기사 제목 + 작성자 이름 + 총 코멘트)을 얻기 위해 다음 쿼리를 사용하고 쿼리 최적화에 의해 그룹에 가입하지만 실행하는 데 시간이 오래 걸립니다 :MySQL은

SELECT article.id, title, username, count(comment.id) AS total_comments 
FROM article 
    LEFT JOIN COMMENT ON comment.article_id = article.id 
    LEFT JOIN user ON article.user_id = user.id 
WHERE STATUS = "open" 
    AND section = "mobiles" 
GROUP BY article.id 
ORDER BY article.id DESC 
LIMIT 0 , 30 

설명의 출력을 is :

id select_type  table type possible_keys key  key_len  ref  rows Extra 
1 SIMPLE article  ALL  status NULL NULL NULL 77 Using where; Using temporary; Using filesort 
1 SIMPLE comment  ref  article_id article_id 5 test.article.id  2  
1 SIMPLE user eq_ref PRIMARY  PRIMARY  4 test.article.user_id 1 

어떻게 임시 테이블을 만들지 않으려면 쿼리를 다시 작성 하시겠습니까?

스토리지 엔진은 MyISAM입니다. 다음은 색인이있는 테이블의 세부 사항입니다.

article 
id, title, body, user_id, status,  section 
primary key: id 
indexes: (user_i),(status,section,id) 


comment 
id, article_id, user_id, body 
primary key: id 
index:(article_id) 


user 
id, username 
primary key: id 
+0

얼마나 오래입니까? 테이블에 몇 개의 행이 있습니까? – michael667

+0

400k 행으로 약 14 초가 소요됩니다. 위의 예는 0.5 초가 걸립니다. 쿼리에서 주석 조인과 개수를 제거하면 0.025 초가 걸립니다. –

답변

1

그룹화 된 조인 대신 하위 쿼리를 사용하면 프로세스가 빨라집니다.

SELECT article.id, title, username, 
     (
     select count(*) from COMMENT 
     where comment.article_id = article.id 
     ) AS total_comments 
FROM article 
    LEFT JOIN user ON article.user_id = user.id 
WHERE STATUS = "open" 
    AND section = "mobiles" 
ORDER BY article.id DESC 
LIMIT 0 , 30 

는 이전 질문 How to make a nested query?

따라 난이 도움이되기를 바랍니다.

+0

고마워요. 그것은 작동합니다! –

1

이 실행 계획은 매우 좋습니다. 임시 테이블을 만들고 정렬하는 것을 피할 수는 없습니다. 쿼리는 그룹화되고 정렬 된 요약 즉, 임시 테이블을 요구합니다. mySQL 서버 프로세스에 더 많은 RAM을 제공하면 디스크상의 테이블 대신 메모리 내장 테이블을 사용할 수 있습니다.