2014-02-21 2 views
0

내가 가진 쿼리 내가 첫 데이트 필터링을 통해 모든 결과를 제거하기 만하면됩니다하지만 당신이 볼 수있는 내가 모든 것을 얻을하고 내 날짜 분류를 할 무엇MySQL의 쿼리 최적화 내부에 가입

$query = "SELECT DISTINCT report_date,weekreportDate FROM contract_sales a 
    INNER JOIN contract b ON a.contract_UUID = b.UUID 
    INNER JOIN geoPoint c ON b.customer_UUID = c.customerUUID 
    WHERE c.com_UUID = '$com' AND a.report_date >= Date('$dateafter') 
    AND c.city_UUID = '$cit' ORDER BY `report_date`"; 

수표에 ..

나는 그들 모두를 속이기 때문에 - 이것을 할 수있는 더 좋은 방법이 있습니까?

나는 각 날짜에 대한 보고서를 가지고 있으며 2 년간의 데이터를 가지고 있습니다. 2014 년에만 날짜를 얻고 싶습니다. 지금 당장은 쓸모없는 700 개 이상의 날짜를 볼 수 있지만 계속해야합니다. 그들 모두는 다른 문자열 UUID도 검사 할 수 있습니다. 느린 구현 임에도 불구하고 작동 속도를 높이려면 어떻게해야합니까? 요청에 따라

정보 설명 : 조회의 재 작성,

Generation Time: Feb 20, 2014 at 06:48 PM 
Generated by: phpMyAdmin 3.3.10.4/MySQL 5.1.53-log 
SQL query: EXPLAIN SELECT DISTINCT report_date,weekreportDate FROM contract_sales a INNER JOIN contract b ON a.contract_UUID = '1234' INNER JOIN geoPoint c ON b.customer_UUID = '1234' WHERE c.com_UUID = '1234' AND a.report_date >= Date('2014-01-01') AND c.city_UUID = '1234' ORDER BY `report_date`; 
Rows: 3 

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE a ref uuid_conlcs uuid_conlcs 110 const 1 Using where; Using temporary; Using filesort 
1 SIMPLE b ref uuid_cust uuid_cust 110 const 1 Using where; Using index; Distinct 
1 SIMPLE c ref uuid_gargp,uuid_citgp uuid_citgp 110 const 1 Using where; Distinct 

답변

1

첫째. 나는 별칭을 단지 a, b, c로 사용하는 것을 제안하지 않겠지 만 contract_sales의 테이블 "cs", 계약의 "con", geoPoint의 "gp"와 같은 좀 더 복잡한 쿼리를 사용하는 것이 더 쉽습니다.

또한 WeekReportDate가 명확하지 않으므로 항상 table.column (또는 alias.column)을 사용하여 쿼리를 한정하려고 시도하지만 계약 판매 테이블과 연결되어있는 것으로 보입니다.

이 구문의 인덱스는 (report_date, weekreportDate, contract_uuid)에 대한 인덱스가 있습니다. 이렇게하면 원시 데이터 페이지로 돌아 가지 않고도 검색되는 열, where 절, order by 및 계약 테이블에 대한 조인을 처리하는 커버 링 인덱스가됩니다.

계약 테이블에서 (UUID, customer_UUID)에 대한 인덱스가 있으며 계약 판매에서 조인을위한 커버 인덱스가 될뿐만 아니라 geoPoint 테이블에 대한 조인을 지원합니다.

마지막으로 geoPoint 테이블. (customerUUID, com_uuid, city_uuid)의 색인으로 조인 및 필터링 기준도 포함합니다. 이제

SELECT DISTINCT 
     cs.report_date, 
     cs.weekreportDate 
    FROM 
     contract_sales cs 
     INNER JOIN contract con 
      ON cs.contract_UUID = con.UUID 
      INNER JOIN geoPoint gp 
       ON con.customer_UUID = gp.customerUUID 
       AND gp.com_UUID = '$com' 
       AND gp.city_UUID = '$cit' 
    WHERE 
     cs.report_date >= Date('$dateafter') 
    ORDER BY 
     cs.report_date 

말했다되고, 나는 볼륨에 대한 당신의 테이블의 구성을 잘 모르겠지만, 특정 COM/도시를위한 재료를 찾고 있다면, 나는 기록 자격이 될 것이라고 의심 것 문제의 날짜 범위에 대해 ALL COM/City보다 훨씬 작은 집합입니다. 그래서, 나는 더 작은 데이터 셋이 더 빨리 쿼리 할 수 ​​있기를 바라는 것처럼 쿼리를 뒤집을 것이다.하지만 분명히 양쪽 모두를 시도해야 할 것이다.

SELECT DISTINCT 
     cs.report_date, 
     cs.weekreportDate 
    FROM 
     geoPoint gp 
     INNER JOIN contract con 
      ON gp.customerUUID = con.customer_UUID 
      JOIN contract_sales cs 
       ON con.UUID = cs.contract_UUID 
       AND cs.report_date >= Date('$dateafter') 
    WHERE 
      gp.com_UUID = '$com' 
     AND gp.city_UUID = '$cit' 
    ORDER BY 
     cs.report_date 

사실 GeoPoint의 인덱스는 다음 테이블에 조인 (com_uuid, city_uuid, customeruuid)에 대한 다음 고객 UUID, 먼저 WHERE 조건에 있어야합니다. 이 쿼리의 조인 흐름에 일치하는 contract_sales 인덱스 (contract_UUID, report_date) 및 계약 테이블 인덱스 (customer_UUID, UUID)입니다.

+0

감사합니다. 그게 당신이 진술 한 것을 소화하기 위해 시간이 좀 걸릴 것 같지만 처음 읽기에서 나는 이해하고 이것이 한 발을 줄 것이라고 생각합니다! 고맙습니다 !! – morty346

+0

@ morty346, 죄송합니다. 늦게 편집하지만, 두 번째 쿼리는 응답 컨텍스트를 개정 할 때 실제로 다른 인덱스를가집니다. – DRapp