통계에 QPC_HISTORY 사용

Henry Hwang -

QPC_HISTORY 사용하기

Clustrix는 클러스터 상태뿐만 아니라 쿼리에 대한 통계를 수집하고 쿼리에 사용된 CPU의 양, 읽은 행, 기록된 행, 실행 횟수 및 실행 시간에 따라 순위를 매깁니다.

때로는 무거운 쿼리가 무엇인지 확인하거나 UI를 사용하지 않고 성능 저하를 파악하려는 경우가 있습니다(UI 쿼리는 동일한CLUSTRIX_STATD.QPC_HISTORY 테이블을 쿼리합니다).

How to Read the Query Logs에서 설명한 대로 쿼리 로그를 파싱할 수도 있지만, 가끔은 쉽고 빠르게 뭔가를 원한다면 CLUSTRIX_STATD.QPC_HISTORY를 쿼리할 수 있습니다.

QPC_HISTORY에서 통계 관련하여 유의해야 할 주요 사항:

  • 통계는 5분마다 수집되어 qpc_history 테이블에 저장됩니다.
  • 각 항목에서 통계 이전 5분의 timestamp에서 수집됩니다.
  • 24시간 보다 오래된 통계는 1시간 항목으로 합쳐진 다음 is_rollup가 1로 설정되고 해당 항목의 모든 통계 해당 timestamp 한시간 이전 것입니다.
  • 순위(Rank)는 쿼리에 사용된 CPU의 양, 읽은 행, 기록된 행, 실행 횟수 및 실행 시간을 기초로 합니다. 순위가 높으면 높을 수록 특정 쿼리가 사용한 자원은 더 많습니다.
  • 7일 보다 오래된 통계는 삭제됩니다.
  • 순위가 100보다 큰 통계는 24시간 후에 삭제됩니다.
  • 때로는 오래되거나 PD(probability distribution)의 변경으로 인해 다시 컴파일 되기 때문에 동일 쿼리가 다른 쿼리 키를 갖게 됩니다.
mysql> describe clustrix_statd.qpc_history;
+-------------------+---------------------+------+-----+-------------------+
| Field             | Type                | Null | Key | Default           | 
+-------------------+---------------------+------+-----+-------------------+
| query_key         | bigint(20) unsigned | NO   | PRI | NULL              | 
| timestamp         | timestamp           | NO   | PRI | current_timestamp | 
| database          | varchar(256)        | YES  |     | NULL              |
| statement         | varchar(8196)       | YES  |     | NULL              |
| exec_count        | int(11) unsigned    | YES  |     | NULL              |
| exec_ms           | bigint(20) unsigned | YES  |     | NULL              |
| exec_us           | bigint(20) unsigned | YES  |     | NULL              |
| avg_exec_ms       | double              | YES  |     | NULL              |
| avg_exec_us       | double              | YES  |     | NULL              |
| min_exec_ms       | double              | YES  |     | NULL              |
| max_exec_ms       | double              | YES  |     | NULL              |
| compile_count     | int(11) unsigned    | YES  |     | NULL              |
| compile_ms        | bigint(20) unsigned | YES  |     | NULL              |
| rows_read         | bigint(20) unsigned | YES  |     | NULL              |
| avg_rows_read     | double              | YES  |     | NULL              |
| rows_written      | bigint(20) unsigned | YES  |     | NULL              |
| avg_rows_written  | double              | YES  |     | NULL              |
| rows_output       | bigint(20) unsigned | YES  |     | NULL              |
| avg_rows_output   | double              | YES  |     | NULL              |
| rank              | int(11) unsigned    | YES  |     | NULL              |
| is_rollup         | tinyint(4)          | NO   | PRI | 0                 |
| rows_inserted     | bigint(20) unsigned | YES  |     | NULL              |
| avg_rows_inserted | double              | YES  |     | NULL              |
| rows_replaced     | bigint(20) unsigned | YES  |     | NULL              |
| avg_rows_replaced | double              | YES  |     | NULL              |
| rows_deleted      | bigint(20) unsigned | YES  |     | NULL              |
| avg_rows_deleted  | double              | YES  |     | NULL              |
+-------------------+---------------------+------+-----+-------------------+
27 rows in set (0.01 sec)

관심을 갖고 볼 주요 컬럼은 다음과 같습니다.

  • timestamp: 이전 5분의 통계가 포함되어 있습니다(24시간 후에 롤업되지 않는 한 이전 시간의 통계가 기록됩니다).
  • exec_count: 이전 통계 시간 동안 이 쿼리에 대한 총 실행수 
  • exec_ms: 해당 기간 동안 쿼리가 걸린 총 시간(ms)
  • avg_exec_ms: 쿼리의 평균 실행 시간. avg_exec_ms 시간이 긴 쿼리는 잠저적인 최적화 후보임니다.
  • max_exec_ms: 최대 실행 시간...max_exec_ms avg_exec_ms를 큰 폭으로 초과하는 경우 추가 조사가 필요할 수 있습니다. 리소스 경합 또는 일부 블락킹 이슈를 나타낼 수 있습니다.
  • rows_read: 통계 시간 동안 읽은 총 행수.
  • avg_rows_read: 쿼리 실행 당 평균 행 읽기. 더 많은 행을 읽으면 클러스터가 더 많은 작업을 처리해야 합니다. 쿼리가 많은 행을 읽어야 할 경우 쿼리 최적화 후보가 될 가능성이 큽니다.
  • rank: 최상위 쿼리를 찾는데 유용합니다.
  • is_rollup: 24시간보다 오래된 통계는 시간별 항목으로 집계됩니다.

실행 횟수로 지난 24시간 동안의 상위 쿼리 찾기(잘못 구성된 애플리케이션 또는 예샹대로 작동하지 않은 일부 테스트 스크립트를 나타낼 수 있습니다).

SELECT query_key, 
       LEFT(statement, 100), 
       Sum(exec_count)           AS exec_count, 
       Round(Avg(avg_rows_read)) AS avg_RR, 
       Round(Avg(avg_exec_ms))   AS avg_exec_ms 
FROM   clustrix_statd.qpc_history 
WHERE  timestamp BETWEEN ( Now() - INTERVAL 24 hour ) AND Now() 
       AND DATABASE != 'clustrix_statd' 
GROUP  BY query_key 
ORDER  BY exec_count DESC, 
          avg_rr DESC;

지난 24시간 동안 읽은 행으로 상위 쿼리 찾기(최적화 되지 않은 쿼리를 나타낼 수 있습니다).

SELECT query_key, 
       LEFT(statement, 100), 
       Sum(exec_count)           AS exec_count, 
       Round(Avg(avg_rows_read)) AS avg_RR, 
       Round(Avg(avg_exec_ms))   AS avg_exec_ms 
FROM   clustrix_statd.qpc_history 
WHERE  timestamp BETWEEN ( Now() - INTERVAL 24 hour ) AND Now() 
       AND DATABASE != 'clustrix_statd' 
GROUP  BY query_key 
ORDER  BY avg_rr DESC, 
          exec_count DESC; 

총 실행 시간별 상위 쿼리 찾기((읽기가 많고)실행하는데 많은 시간이 소요되는 복잡한 쿼리를 나타낼 수 있습니다).

SELECT query_key, 
       LEFT(statement, 100), 
       Sum(exec_count)           AS exec_count, 
       Round(Avg(avg_rows_read)) AS avg_RR, 
       Round(Avg(avg_exec_ms))   AS avg_exec_ms 
FROM   clustrix_statd.qpc_history 
WHERE  timestamp BETWEEN ( Now() - INTERVAL 24 hour ) AND Now() 
       AND DATABASE != 'clustrix_statd' 
GROUP  BY query_key 
ORDER  BY avg_exec_ms DESC, 
          exec_count DESC; 

 마지막으로, 상위 3에 랭크된 30개의 쿼리 살펴보기

SELECT timestamp, 
       DATABASE, 
       rank, 
       LEFT(statement,100), 
       exec_count, 
       avg_rows_read, 
       avg_exec_ms 
FROM   clustrix_statd.qpc_history 
WHERE  rank <4 AND DATABASE !='clustrix_statd' ORDER BY timestamp DESC, rank ASC LIMIT 30;


몇 가지 팁

  • 문제가 발생한 시간을 아는 경우 timestamp 기간을 좁히십시오.
  • 어떤 테이블이 이 문제의 원인인지 아는 경우 다음과 같이 like와 함게 where절에 테이블 이름을 명시하십시오: where statement like '%table_name%'
  • 쓰기 쿼리에 관심이 있다면 rows_written을 살펴보십시오.
  • 쿼리가 정상보다 느리게 실행되는 것 같으면 해당 쿼리가 정상적으로 실행될 때의 avg_exec_ms을 비교하여 같은 시간대에서 다른 쿼리가 실행되고 있는지 확인하십시오. 리소스 경합을 나타낼 수 있습니다(다른 무거운 실행중 쿼리 또는 블락킹 쿼리). 쿼리 로그와 함께 clustrix_statd.QPC_HISTORY를 보면 도움이 될 것입니다.
또 다른 질문이 있으십니까? 문의 등록

0 댓글

댓글을 남기려면 로그인하세요.
Zendesk 제공