2014-09-08 2 views
-1
SELECT 
    cast(t1.destination as unsigned) as prefix, 
    t2.destination as destination, 
    FORMAT(sum(t1.terminatecauseid = 1), 0) as calls, 
    IFNULL(sec_to_time(avg(case when t1.terminatecauseid = 1 then t1.sessiontime end)), 0) as aloc, 
    CONCAT(TRUNCATE(sum(t1.terminatecauseid = 1) * 100/count(*), 1), '%') as asr, 
    sum(case when t1.terminatecauseid = 1 then t1.sessiontime end) as duration 
FROM 
    cc_call AS t1 
     inner join 
    cc_prefix as t2 ON t1.destination = t2.prefix 
     inner join 
    cc_country as t4 ON t1.destination like CONCAT(t4.countryprefix, '%') 
WHERE 
    t1.card_id = '133' AND t1.starttime >= ('2014-06-1') 
group by t4.countryprefix 
having duration is not null 
order by duration DESC 
LIMIT 0 , 25 

검색 엔진을 만드는 중, 필자는 필요한 정보를 얻기 위해 올바른 쿼리를 제안했습니다. DB가 크고 (1GB) 쿼리가 언젠가 httpd 서버를 중단시킵니다.MySQL 검색 쿼리가 매우 느림

이 쿼리는 실행되고 페이지 순위를 결정하는 페이지 매김에 대해 비슷한 쿼리가 실행되며 총 지속 시간과 통화에 대해 세 번째 쿼리가 실행됩니다.

이 모든 것이 결합되면 성능이 매우 저하됩니다. 여기에 db 예제가 있습니다 sqlfiddle

성능 향상 방법에 대한 조언을 언제든지 환영합니다.

결과를 좁히기 위해 다른 검색어와 함께 '보기'를 사용하려고 시도했지만 아직 행운이 없습니다.

+0

어떤 색인이 있습니까? 기본 또는 선언 된 보조 키에 대한 조인입니까? – Philipp

+0

편의상 sqlfiddle를 제공 ​​했으므로 인덱스를 고려하지 않고 조인을 만들었습니다. –

+1

인덱스가없는 필드의 JOIN은 전체 테이블 스캔이 필요합니다. 쿼리가 느려지는 것은 당연합니다. – Philipp

답변

0

DB의 구조를 변경할 수 없으며 와일드 카드 검색에 정말 오랜 시간이 걸리므로 mysql View을 사용하기로 결정했습니다.

보기에서 확장명으로 그룹화 된 모든 통화를 조회 한 후 와일드 카드 검색으로 다른보기를 작성했습니다 (모든 DB를 처음부터 끝까지 재검토하는 것보다 빠름).

총 통화 쿼리 및 페이지 매김을 도왔습니다. 응답 시간은 정말 좋습니다.