2011-03-14 2 views
0

저는 데이터 마이닝 프로젝트에서 코드 요소와 관계 및 시간 경과에 따른 이러한 변경 사항을 살펴보고 있습니다. 우리가 원하는 것은 관련 요소가 얼마나 자주 변경되는지 몇 가지 질문을하는 것입니다. 보기로 설정했지만 실행하는 데 10 분 정도 소요됩니다. 문제는 필자가 창 크기에 대한 항목을 비교하기 위해 뺄셈, 연결 및 문자열 비교를 많이해야한다는 것입니다.하지만이를 해결할 좋은 방법을 모르겠습니다. 쿼리는특정 SQL 쿼리 최적화 도움말 필요

같은
select aw.same 
    , rw.k 
    , count(distint concat_ws(',', r1.id, r2.id)) as num 
    from deltamethoddeclaration dmd1 
    join revision r1 
     on r1.id=FKrevID 
    join methodinvocation mi 
     on mi.FKcallerID = dmd1.FKMDID 
    join deltamethoddeclaration dmd2 
     on mi.FKcalleeID = dmd2.FKMDID 
    join revision r2 
     on r2.id = dmd2.FKrevID 
    join revisionwindow rw 
    join authorwindow aw 
    where (dmd1.FKrevID - dmd2.FKrevID) < rw.k 
    and (dmd2.FKrevID - dmd1.FKrevID) < rw.k 
    and case aw.same 
      when 1 then 
      r1.author = r2.author 
      when 0 then 
      r1.author <> r2.author 
      else 
      1=1 
     end 
    group by aw.same 
     , rw.k 
; 

좋아, 그래서 revisionwindow 상점 ​​우리가 관심있는 수정 창 (10, 20, 50, 100) 및 authorwindow 저자 유형 우리는 (같은, 다른 원과 그렇지 않은 매장을 찾습니다 케어). 문제의 일부는 서로 다른 요소가 일치하는 동일한 수정 쌍을 가질 수 있기 때문에 유일한 해킹은 추한 개수 (별개의 concat()) 것입니다. 이렇게하면 작성자와 개정 본의 조합마다 하나씩 12 행의 테이블이 반환됩니다. 'num'아래의 항목은 지정된 방식으로 관련된 수정 본의 고유 한 쌍입니다 (이 경우 변경 방법과 두 방법 중 하나가 다른 방법을 호출 함). 그것은 완벽하게 작동, 그것은 단지 미친 느린 (~ 10 분 실행 시간). 나는 기본적으로 정확성을 희생하지 않으면 서이 작업을 더 잘 수행 할 수 있도록 조언이나 도움을 구하고 있습니다.

+0

모든 기본/외래 키에 대한 색인이 있습니까? 각 테이블의 행은 몇 개입니까? –

+0

'methodinvocation'에 몇 개의 레코드가 있습니까? – Quassnoi

+0

모든 키가 색인됩니다. methodinvocation 테이블에는 약 110,000 개의 항목이 있습니다. deltamethoddeclaration에 120K 항목이 있고 수정 버전이 14K입니다. –

답변

0

두 조건 (join revisionwindow rw) 및 (join authorwindow aw)에 ON 조건이 없지만 WHERE를 사용하면이 문제가 발생합니다.

이 두 테이블에는 몇 개의 레코드가 있습니까? MySQL은 아마도 이것들에 대해 CROSS JOIN을 먼저 수행하고 나중에 복잡한 (WHERE) 조건을 검사 할 것이다.

그러나 EXPLAIN의 결과를 게시하십시오.

--EDIT--
두 개의 테이블에 4와 3 개의 행이 있다고 설명하는 마지막 단락이 누락되었습니다.

당신이 시도 할 수 :합니다 (CONCAT이와 어디 절은 ON 가입으로 이동 한 대체되었습니다 ...)

select aw.same 
    , rw.k 
    , count(distint r1.id, r2.id) as num 
    from deltamethoddeclaration dmd1 
    join revision r1 
     on r1.id = dmd1.FKrevID 
    join methodinvocation mi 
     on mi.FKcallerID = dmd1.FKMDID 
    join deltamethoddeclaration dmd2 
     on mi.FKcalleeID = dmd2.FKMDID 
    join revision r2 
     on r2.id = dmd2.FKrevID 
    join revisionwindow rw 
     on (dmd1.FKrevID - dmd2.FKrevID) < rw.k 
     and (dmd2.FKrevID - dmd1.FKrevID) < rw.k 
    join authorwindow aw 
     on case aw.same 
      when 1 then 
      r1.author = r2.author 
      when 0 then 
      r1.author <> r2.author 
      else 
      1=1 
      end 
    group by aw.same 
     , rw.k 
; 
1
  • 곳 (dmd1.FKrevID - dmd2.FKrevID) < rw.k이 문에 대한 가장 손상이 연산자 <보다 마에 작지

    그는 산술. B- 트리는 이것을 사용할 수 없으며 언제든지 전체 테이블 스캔을 강제 실행합니다. 왜이 사실 피투성이 세부 정보 :

  • http://explainextended.com/2010/05/19/things-sql-needs-determining-range-cardinality/ 내가 당신 CASE 문을 의심 백엔드 최적화 할 수 있으며 <> 운영자는 위와 같은 문제에서 겪고있다. = 연산자를 사용하는 방법에 대해 생각해보십시오. 아마도 쿼리를 분리하고 UNION 문을 사용하여 항상 인덱스를 사용할 수 있습니다.

  • EXPLAIN을 사용하고 있지 않습니다. 쿼리를 최적화하려면이 기능을 사용해야합니다. 어떤 인덱스가 사용 중인지, 어떤 인덱스가 유용하지 않은지, 또는 조건이 도움이 될만한 위치에서 선택적인 것인지 알 수 없습니다 (매우 선택적이 아닌 경우 마지막 점 참조) http://dev.mysql.com/doc/refman/5.0/en/explain.html

  • 데이터 마이닝 응용 프로그램이므로 중간 값의 임시 테이블을 사용할 수있는 좋은 기회입니다.데이터가주기적인 간격으로 (또는 한 번만!) 덤핑 될 수 있기 때문에 데이터 손상 위험없이 자주 실행되는 임시 테이블을 쉽게 재구성 할 수 있습니다 (또는 집계 패턴을 찾는 것부터 중요하지 않을 수도 있습니다 .)

    나는 어려운 항목을 캐싱 한 임시 테이블을 작성하여 60 분이 넘은 쿼리를 가져 와서 100 밀리 초 (즉시)로 줄였습니다. 위의 아이디어를 사용할 수 없다면 아마도 이것이 아마도 가장 낮은 열매입니다. 모든 '어려운 일'- 사례 조인과 비평립 조인을 한 곳에서 수행하십시오. 그런 다음 임시 테이블에 인덱스를 추가하십시오 :-) 트릭은 임시 테이블을 쿼리 할 수 ​​있도록 일반화하여 다른 질문을 할 수있는 유연성을 제공합니다.

+0

nate 내에서 모든 표현식을 연결해야합니다. 주석을 주셔서 감사합니다. 이전에 이런 일을하지 않은 것이 확실합니다.이 문제를 해결하는 방법에 대한 구체적인 지침을 알려주십시오. 두 개의 키를 뺀 것이므로 첫 번째 링크에서 논의 된 범위 트릭을 계속 사용할 수 있습니까? 아니면 임시 테이블에 무엇을 넣을 지와 사용 방법에 대한 예를 들어 줄 수 있습니까? –

+0

@ 카일 : 미리 계산 된 인덱스를 사용할 수는 있지만, 한 테이블의 상수와 값만 사용할 수 있으므로이 경우에는 작동하지 않습니다 (자체 조인이 아닌). 임시 테이블을 만든 다음 인덱스를 추가하는 것이 좋습니다. –

+0

@ 카일 : 많은 선택성없이 대부분의 행을 스캔하는 것처럼 보이지만 인덱스가 주요 문제인지는 확실하지 않습니다. 자신이하는 일에 상관없이 전체 테이블 스캔이 이루어질 수 있습니다. 나는 id의 차이와 동일한 작성자 표현식을 사용하여 임시 테이블을 미리 계산하는 것에 대해 열심히 생각할 것입니다.데이터를 사전 집계 할 수 있다면 쿼리가 매우 빠르게 작동 할 수 있습니다. 그런 다음 리비전 및 제작자 윈도우 항목으로 임시 테이블을 쿼리합니다. –