2016-12-08 1 views
0

보고서를 생성하는 데 사용하는 쿼리를 최적화하려고합니다. 나는 약간 확장하기에 확실히 좋게 만들었다 것을 나는 생각한다. 내가 추가 열에서 실행이 일반 볼 때범위 쿼리에서 MySQL의 인덱스를 사용하지 않습니다.

select trat.asset_name as group_name,trat.name as sub_group_name, 
     trat.asset_id as group_id, 
     if(trat.cause_task_type='AccessRequest',true,false) as is_request_task, 
     '' as grouped_on, 
     concat(trat.asset_name,' - {0} (',count(*),')') as table_heading 
    from t_remote_agent_tasks trat 
    where trat.status in ('completed','failedredundant') 
     and trat.name not in ('collect-data','update-conn-params') 
    group by trat.asset_name, trat.name 
    order by field(trat.name,'create-account','change-attr', 
          'add-member-to-group', 
          'grant-access','disable-account','revoke-access', 
          'remove-member-from-group','update-license') 

는, filesort를 임시 사용하여 위치를 사용하여 말한다 : 다음은 원래 쿼리이었다.

그래서 나는 최적화 나에게 일시 사용, 어디에 사용하는 것과 실행 계획을주는이

select trat.asset_name as group_name,trat.name as sub_group_name, 
     trat.asset_id as group_id, 
     if(trat.cause_task_type='AccessRequest',true,false) as is_request_task, 
     '' as grouped_on, 
     concat(trat.asset_name,' - {0} (',count(*),')') as table_heading 
    from t_remote_agent_tasks trat 
    where trat.status in ('completed','failedredundant') 
     and trat.name not in ('collect-data','update-conn-params') 
    group by trat.asset_name,trat.name 
    order by null 

같은 쿼리. 따라서 filesort는 더 이상 사용하지 않으며 옵티마이 저는 정렬 할 필요가 없으므로 추가 오버 헤드가 없으며 그룹별로 처리됩니다.

그룹별로 언급 한 순서대로 그룹별로 색인을 생성했습니다 (중요하거나 최적화되지 않습니다). 즉 (trat.asset_name, trat.name)에 색인을 생성합니다. 이제이 최적화는 나를 여분의 열에 만 사용합니다. 또한 쿼리 실행 시간은 거의 절반으로 추측됩니다 (이전에는 0.568 초 였지만 현재는 0.345 초입니다. 정확하지는 않지만 매번 변경되지만이 범위에서 더 많거나 적음).

가 지금은 쿼리의 일부가 아래 범위 쿼리를 최적화 할

trat.status in ('completed','failedredundant') 
and trat.name not in ('collect-data','update-conn-params') 

내가하지 말한다 mysl reference guide to optimize range query에 읽고있다 범위 쿼리에없는, 그래서 나는이

같은 쿼리에서 수정을했다
trat.status in ('completed','failedredundant') 
and trat.name in ('add-member-to-group','change-attr','create-account', 
        'disable-account','grant-access', 'remove-member-from-group', 
        'update-license') 

그러나 Extra에서는 아무런 개선점도 보이지 않습니다. (색인을 사용해야 함은 여전히 ​​어디에서 사용하고 있는지 나타냅니다.) 또한 두 범위 부분을 유니온으로 분할하여 시도했지만 쿼리 결과는 변경되지만 실행 계획은 개선되지 않습니다.

이 쿼리를 더 많이 최적화하는 방법에 대한 도움이 필요합니다. 대부분 범위 부분 (부분적으로) . 다른 최적화가 필요하다면 어떻게해야합니까?

은 내가, 나 또한 trat.status에 인덱스가 언급에 잊었다 미리 감사드립니다

EDIT 1 그래서 다음은 인덱스

  1. (trat.asset_name, 뜨랏입니다, 당신의 시간을 주셔서 감사합니다. 이름)
  2. (trat.status) 거의 모든 경우에

답변

0

는, 하나의 인덱스는 SELECT에 사용됩니다. 그래서, 하나는 최고가 있어야합니다. 처음 두 쿼리의

아마 혜택 같은 '복합'지수에서 가장 것

INDEX(asset_name, name) 

일반적으로, 하나는 인덱스에서 WHERE 조건을 처리하려고 할 것입니다,하지만 그들은 보이지 않는 색인에 따라야한다. (아래의 추가 토론.) 두 번째 선택은 GROUP BY입니다.그러나 (첫 번째 경우) ORDER BYGROUP BY이 다르므로 GROUP BY의 출력을 위해 생성 된 tmp 테이블이 있어야 ORDER BY에 따라 정렬 될 수 있습니다. (GROUP BY에 대한 tmp 및 정렬이있을 수도 있지만 알 수 없습니다.)

"색인 사용"은 "포함"색인이 사용되었음을 의미합니다. "덮음"색인은 을 포함하는 복합 색인입니다. 어디서나 열을 사용하면 SELECT에 이 사용됩니다. 그건 약 5 열이고 아마 시도하는 것이 현명하지 않을 것입니다.

WHERE x IN (11,22) 
GROUP BY y 

WHEREGROUP BY을 모두 처리 할 수있는 인덱스를 사용할 수 없습니다. (더 아래)

또 다른 것은이 간단한 심지어 뭔가주의합니다. 따라서 쿼리가 두 가지 모두를 소비 할 수있는 방법은 없습니다 ('covering'제외).

커버 인덱스는 부분적으로 만 유용합니다. 모든 작업은 색인의 BTree에서 바로 수행됩니다. 그러나 전체 인덱스 스캔을 포함 할 수 있습니다. 전체 테이블 스캔보다 훨씬 빠릅니다. 이것은 '덮음'을 권장하지 않는 또 다른 주장이다. 어떤 상황에서

IN 또는 ORUNION로 돌려 속도를 높일 수 있습니다

(SELECT ... WHERE status in ('completed')) 
UNION ALL 
(SELECT ... WHERE status in ('failedredundant')) 

그러나 이것은 당신이 IN보다 더 인 NOT IN(...) 절에 넘어에만 발생합니다.

최상의 색인을 찾는 목적은 색인 또는 표에있는 행이 BTree에 연속적으로있는 것을 찾는 것입니다.

이 쿼리에 더 개선 할 것입니다 아마 필요 다시 생각 스키마를 - 당신이 IN, NOT IN, FIELD 및 기타 어려운 최적화 구조를 가지고 강제 것으로 보인다.

+0

덕분에 많은 도움이됩니다. – user3817378

관련 문제