2010-01-31 5 views
1

일부 쿼리 테스트에서 EXPLAIN을 실행하면 인덱스조차도 모든 조인 속도가 느려집니다.
다음 정보를 사용하여 MYSQL 쿼리를보다 효율적으로 만들 수 있습니까?MYSQL (3) 테이블 조인 쿼리 최적화

테이블

카운터

: ID (PK), 타임 스탬프, USER_ID (FK)
사용자 : ID (PK), 사용자 이름, website_id (FK)
사이트 : id (pk), 사이트 이름

SELECT t2.username, t3.sitename, count(*) as views FROM counter t1 
LEFT JOIN user t2 ON t2.id = t1.user_id 
LEFT JOIN website t3 ON t3.id = t2.website_id 
WHERE t1.id <> "" 
GROUP BY t1.id 
ORDER BY t1.id DESC 

HTML 테이블에 결과 :

사용자 이름, 사이트 이름이

+0

내 질문에 올바른 SQL을 참조하십시오. – Hogan

답변

1

데이터가 아직 채워 집니까? 이 테이블이 비어 있거나 매우 작 으면 전체 테이블이 한 페이지에 있기 때문에 옵티마이 저가 '모든'쿼리를 선택할 수 있습니다. 전체 테이블을 확보하기 위해 디스크에서 한 페이지로드하는 것이 인덱스의 디스크 페이지를 누른 다음 실제 데이터 페이지의 다른 페이지를 누르는 것보다 빠릅니다.

+0

데이터가 비교적 작습니다. 카운터 6000, 사용자 100, 사이트 10입니다. – rrrfusco

+1

카운터 테이블은 아마도 두 페이지에 있지만, 그렇다고하더라도 전체 테이블 (2 페이지)을 메모리에로드하는 것은 페이지에서 동일한 비용이 최소 인덱스 조회에 도달합니다. 그래서 나는 '모든'조인에 놀라지 않습니다. 테이블의 크기를 일괄 적으로 늘리더라도 동작이 지속됩니까? 예를 들면 100 번? – TheDon

2

대신하지 count(*)를 수행 사용 counter_views count(t1.id)

질문 편집 변경

질문을 편집 할 때 count 문에 집계 할 항목을 입력해야합니다. count(user.id)

나는 SQL이 잘못되었다고 생각합니다. Do not do this :

select u.username, s.sitename, count(c.id) 
from user u 
join website s on u.website_id = s.id 
join counter c on u.id = c.user_id 
where u.id <> "" 
group by u.username, s.sitename 
order by u.id desc 
+0

예, 참여할 때 지정할 필요가 있습니다. –

+0

궁극적으로 ORDER BY 뷰 [count (c.id)를 뷰로 사용]하고 싶지만 EXPLAIN은 filesort를 사용하여 모든 join, NULL 키를 임시로 사용합니다. 더 좋은 방법이 있습니까? – rrrfusco

+0

@rrrfusco 어떤 색인을 설정 했습니까? – Hogan

0

검색어가 잘못되었습니다. 나는 다음과 같이 사용할 것이다 :

SELECT u.username, w.sitename, c.views 
FROM (
    SELECT user_id, COUNT(*) AS views FROM counter GROUP BY user_id 
) AS c 
LEFT JOIN user u ON u.id = c.user_id 
LEFT JOIN website w ON w.id = u.website_id 
ORDER BY c.views DESC 

나는 counter.user_id에 대한 색인도 추가 할 것이다.

+0

user_id에 색인이 있습니다. 나는 항상 subselects에 문제가있었습니다. phpmyadmin이 c.user_id가 알 수없는 열임을 알려줍니다. 우 ... ..이 시간이 좀 걸릴 것입니다 ... – rrrfusco

+0

이 쿼리는 틀립니다. 사용자가 웹 사이트를 두 개 이상 가지고 있으면 (디자인에서 알 수 있듯이) 작동하지 않습니다.사용자 웹 사이트에 일대일 관계가있는 경우 하위 쿼리 대신 조인을 사용하는 쿼리가 빠릅니다. (하위 쿼리는 서버가 최적화하지 않는 한 종종 매우 느립니다.) – Hogan

+0

디자인 웹 사이트에 몇 사용자가있을 수 있습니다 제안, 디자인에 대한 쿼리를 했어. 음, 하위 쿼리가 느리다는데 동의합니다. GROUP BY가 있으면 FROM 섹션에서만 사용합니다. 코드를 훨씬 쉽게 읽을 수 있기 때문입니다. 이 MySQL quirk을 좋아하지 않습니다. 필드가 GROUP BY 문에 없으면 집계 함수를 사용합니다. – Michas