2009-05-07 6 views
0

현재 일부 최적화가 필요한 웹 사이트에서 작업 중입니다 ... 프론트 페이지가로드되는 데 약 15-20 초가 걸리기 때문에 몇 가지 최적화가 좋을 것이라고 생각했습니다. 또한 id가 기본 키가 perso_id이 - (이메일 및 프로파일이 포함되어 ~ 207K 라인) profil_persoMySQL 쿼리 최적화

SELECT a.user,a.id 
FROM `profil_perso` pp 
INNER JOIN `acces` a ON pp.parrain = a.id 
INNER JOIN `acces` ap ON ap.id = pp.id 
WHERE pp.parrain_visibilite = '1' 
    AND a.actif = 1 
GROUP BY a.id 
ORDER BY ap.depuis DESC LIMIT 15; 

: 여기

는 MySQL의 느린 쿼리 로그에 출연 한 쿼리입니다 (foreign key) + parrain (referer) + parrain_visibilite (referer is shown)이 인덱스입니다.

처음 : 1.94532990456
마지막 시간 : 1.94532990456 acces

벤치 마크 색인 (등록 날짜)가 실제로 보여줍니다 또한 depuis, 기본 키는 그 id있다
평균 시간 :

: 0.0389438009262

나는 시도는 이런 식으로 넣어 아직 691,363,210

SELECT DISTINCT a.id, a.user 
FROM `profil_perso` pp 
LEFT JOIN `acces` a ON pp.parrain = a.id 
WHERE pp.parrain_visibilite = 1 
    AND a.actif = 1 
    AND pp.id != 0 
ORDER BY pp.id DESC LIMIT 15; 

벤치 마크 공연이 :

처음 : 1.96376991272
마지막 시간 : 1.96376991272
평균 시간 : 0.0393264245987

쿼리 시간을 낮추기 위해 어떤 힌트?

여기 전체 인덱스 :

대한 액세스 :

id (primary) 
derniere_visite -- last visit 
pays_id -- country_id 
depuis -- registration time 
perso_id -- foreign key to profil_perso primary key 
actif -- account status 
compte_premium -- if account is premium 

profil_perso :

perso_id (primary) 
id -- foreign key to acces primary key 
genre -- gender 
parrain_visibilite -- visibility of referer 
parrain -- referer 
parrain_contexte 
telephone 
orientation 
naissance -- birthdate 
photo -- if it has a picture 
+0

3 개의 테이블에 전체 색인을 게시 할 수 있습니까? 문제에 관해서는 내 최선의 추측이지만 확실하게보아야 할 것입니다. – MBCook

+0

이 모든 것들은 acces.id, acces.ap acces.parrain indexed입니까? – THEn

+0

출력을 원하는대로 설명 할 수 있다면 도움이 될 것입니다. – Greg

답변

3

실행하면 인덱스를 누락 될 수 있습니다 곳 당신을 보여 도움이 될 것입니다 EXPLAIN SELECT DISTINCT a.id .....;

+0

쿼리를 통해 최적화 쿼리를 볼 수있게하기 전에 EXPLAIN 명령을 실행하는 것에 동의합니다. 유용한 링크 http://dev.mysql.com/doc/refman/5.0/en/using-explain.html http://dev.mysql.com/doc/refman/5.0/en/explain.html –

+0

MySQL이 쿼리를 실행하는 방법을 알기 전까지는 런타임을 최적화하는 데 더 많은 피해를 줄 수 있습니다. EXPLAIN을 사용하면 MySQL이 쿼리를 실행하는 방법을 분석 할 수 있습니다. –

+0

+1 설명 실행 –

0

왜 여기에 두 개의 JOIN이 있습니까? profil_perso (parrain, parrain_visibilite)에 복합 인덱스를 생성,

CREATE INDEX ix_acces_actif_depuis ON acces (actif, depuis) 

을 :

acces (actif, depuis)에 복합 인덱스를 생성

CREATE INDEX ix_profilperso_parrain_parrainvisibilite ON profil_perso (parrain, parrain_visibilite) 

을이 시도 :

SELECT a.user, a.id 
FROM acces a 
JOIN profil_perso p 
ON  pp.parrain = a.id 
     AND pp.parrain_visibilite = 1 
WHERE a.actif = 1 
ORDER BY 
     a.actif DESC, a.depuis DESC 
LIMIT 15 

이 쿼리는 인덱스를 사용합니다 정렬을 피하기 위해 actifprofil_perso에있는 색인을 찾아서 보이지 않는 parrain을 찾아서 걸러냅니다.

여기에 LIMIT 15이 있으므로이 쿼리는 즉시 수행되어야합니다.

actif 필드가 얼마나 선택적인지 알면 도움이됩니다.

이 파악하려면 다음을 실행하십시오 :

SELECT COUNT(DISTINCT actif)/COUNT(*) 
FROM acces 
+0

우리는 여기 근처에 있습니다. 쿼리는 훨씬 좋지만 문제가 있습니다. 쿼리는 중복을 생성합니다 (한 사람이 몇 명의 사용자를 추천 할 수 있습니다 ...). 명령문별로 그룹을 추가하면 쿼리가 1-2 초로 돌아갑니다. 뚜렷한 것을 사용하는 것은 더욱 악합니다. – Erick

+0

샘플 데이터를 게시 할 수 있습니까? – Quassnoi

0

적절한 answerr (들) 데이터의 분포에 많은 (레코드 수, 필드의 기수 및 필드 조합 등) AMD 스키마를 따라 , 쿼리 식과 같습니다. 그 정보가 주어 지더라도 우리는 테스트를위한 제안만을 제공 할 수 있었으며, 이는 테스트를위한 더 많은 제안으로 이어질 것입니다.

그러나 우리는 관련된 테이블의 스키마와 함께 현재 EXPLAIN의 결과 (twise, second 및 first results 실행)로 시작하여 시작할 수 있습니다.

0

일반적으로 기본 키뿐만 아니라 테이블 조인에 사용 된 외래 키에 대한 indecies가 올바르게 설정되어 있는지 확인해야합니다.

또한 일반적으로 필터링/주문할 모든 필드에 대해 indecies를 정의하는 것이 바람직합니다. 따라서 다시 적절하게 설정해야합니다.

그러나 여기서는 큰 실적이 207,000 개의 레코드를 정렬하여 마지막 15 개의 레코드를 정렬하는 것일 수 있다고 생각합니다. 다른 방식으로 동일한 결과를 얻을 수 있습니까?