지표
지표 (Metrics)
DuckDB는 데이터베이스의 성능과 상태를 모니터링하는 데 사용할 수 있는 지표(metric) 집합을 제공해요.
출처: 문서
본문
쿼리 트리에는 QUERY_ROOT와 OPERATOR 두 가지 타입의 노드가 있어요. QUERY_ROOT는 최상위 노드만을 가리키며, 여기에 포함된 지표는 전체 쿼리에 대해 측정돼요. OPERATOR 노드는 쿼리 플랜의 개별 연산자를 가리켜요. 일부 지표는 QUERY_ROOT 노드에서만, 다른 것들은 OPERATOR 노드에서만 사용할 수 있어요. 아래 표는 각 지표와 그것이 사용 가능한 노드를 설명해요.
OPERATOR_TYPE 외에는 모든 지표를 켜거나 끌 수 있어요.
모든 지표 (All Metrics)
지표 그룹 (Metric Groups)
지표는 그룹으로 정리되어 있으며, 관련 지표를 함께 활성화/비활성화하는 데 사용할 수 있어요. 사용 가능한 지표 그룹 목록은 다음과 같아요.
핵심 지표 (Core Metrics)
핵심 지표.
CPU_TIME
| Description | 쿼리에 소요된 CPU 시간 | | Type | double | | Unit | seconds | | Default | ✅ | | Query Node | ✅ | | Operator Node | ✅ | | Cumulative | ✅ | | Child | OPERATOR_TIMING |
참고:
CPU_TIME은 누적 연산자 타이밍을 측정해요. 파싱, 쿼리 플래닝 같은 다른 단계에 소요된 시간은 포함하지 않아요. 따라서 일부 쿼리에서는 QUERY_ROOT의 LATENCY가 CPU_TIME보다 클 수 있어요.
CUMULATIVE_CARDINALITY
| Description | 쿼리의 누적 카디널리티 | | Type | uint64 | | Unit | absolute | | Default | ✅ | | Query Node | ✅ | | Operator Node | ✅ | | Cumulative | ✅ | | Child | OPERATOR_CARDINALITY |
CUMULATIVE_ROWS_SCANNED
| Description | 쿼리가 스캔한 행의 누적 수 | | Type | uint64 | | Unit | absolute | | Default | ✅ | | Query Node | ✅ | | Operator Node | ✅ | | Cumulative | ✅ | | Child | OPERATOR_ROWS_SCANNED |
EXTRA_INFO
| Description | 고유 연산자 지표 | | Type | Value::MAP | | Default | ✅ | | Query Node | ✅ | | Operator Node | ✅ |
LATENCY
| Description | 전체 쿼리를 실행하는 데 소요된 시간 | | Type | double | | Unit | seconds | | Default | ✅ | | Query Node | ✅ |
QUERY_NAME
| Description | 쿼리의 SQL 문자열 | | Type | string | | Default | ✅ | | Query Node | ✅ |
RESULT_SET_SIZE
| Description | 결과의 크기 | | Type | uint64 | | Unit | bytes | | Default | ✅ | | Query Node | ✅ | | Operator Node | ✅ | | Child | RESULT_SET_SIZE |
ROWS_RETURNED
| Description | 쿼리가 반환한 행 수 | | Type | uint64 | | Unit | absolute | | Default | ✅ | | Query Node | ✅ | | Child | OPERATOR_CARDINALITY |
실행 지표 (Execution Metrics)
쿼리 실행 중에 수집되는 지표.
BLOCKED_THREAD_TIME
| Description | 스레드를 사용할 수 있을 때까지 기다린 시간 | | Type | double | | Unit | seconds | | Default | ✅ | | Query Node | ✅ |
SYSTEM_PEAK_BUFFER_MEMORY
| Description | 시스템의 최대 메모리 사용량 | | Type | uint64 | | Unit | bytes | | Default | ✅ | | Query Node | ✅ | | Operator Node | ✅ |
SYSTEM_PEAK_TEMP_DIR_SIZE
| Description | 임시 디렉터리의 최대 크기 | | Type | uint64 | | Unit | bytes | | Default | ✅ | | Query Node | ✅ | | Operator Node | ✅ |
TOTAL_MEMORY_ALLOCATED
| Description | 버퍼 매니저가 할당한 총 메모리. | | Type | uint64 | | Unit | bytes | | Default | ✅ | | Query Node | ✅ |
파일 지표 (File Metrics)
파일 연산 중에 수집되는 지표.
ATTACH_LOAD_STORAGE_LATENCY
| Description | 스토리지에서 로드하는 데 소요된 시간. | | Type | double | | Unit | seconds | | Default | ✅ | | Query Node | ✅ |
ATTACH_REPLAY_WAL_LATENCY
| Description | WAL 파일을 재생하는 데 소요된 시간. | | Type | double | | Unit | seconds | | Default | ✅ | | Query Node | ✅ |
CHECKPOINT_LATENCY
| Description | checkpoint 실행에 소요된 시간 | | Type | double | | Unit | seconds | | Default | ✅ | | Query Node | ✅ |
COMMIT_LOCAL_STORAGE_LATENCY
| Description | 트랜잭션 로컬 스토리지를 커밋하는 데 소요된 시간. | | Type | double | | Unit | seconds | | Default | ✅ | | Query Node | ✅ |
TOTAL_BYTES_READ
| Description | 파일 시스템이 읽은 총 바이트. | | Type | uint64 | | Unit | bytes | | Default | ✅ | | Query Node | ✅ |
TOTAL_BYTES_WRITTEN
| Description | 파일 시스템이 쓴 총 바이트. | | Type | uint64 | | Unit | bytes | | Default | ✅ | | Query Node | ✅ |
WAITING_TO_ATTACH_LATENCY
| Description | 파일 ATTACH를 기다리는 데 소요된 시간. | | Type | double | | Unit | seconds | | Default | ✅ | | Query Node | ✅ |
WAL_REPLAY_ENTRY_COUNT
| Description | WAL에서 재생할 항목의 총 수. | | Type | uint64 | | Unit | absolute | | Default | ✅ | | Query Node | ✅ |
WRITE_TO_WAL_LATENCY
| Description | WAL에 쓰는 데 소요된 시간. | | Type | double | | Unit | seconds | | Default | ✅ | | Query Node | ✅ |
연산자 지표 (Operator Metrics)
각 연산자에 대해 수집되는 지표.
OPERATOR_CARDINALITY
| Description | 연산자의 카디널리티 | | Type | uint64 | | Unit | absolute | | Default | ✅ | | Operator Node | ✅ |
OPERATOR_NAME
| Description | 연산자의 이름 | | Type | string | | Default | ✅ | | Operator Node | ✅ |
OPERATOR_ROWS_SCANNED
| Description | 연산자가 스캔한 행 수 | | Type | uint64 | | Unit | absolute | | Default | ✅ | | Operator Node | ✅ |
OPERATOR_TIMING
| Description | 연산자에 소요된 시간 | | Type | double | | Unit | seconds | | Default | ✅ | | Operator Node | ✅ |
OPERATOR_TYPE
| Description | 연산자의 타입 | | Type | uint8 | | Default | ✅ | | Operator Node | ✅ |
단계 타이밍 지표 (Phase_timing Metrics)
이 그룹은 플래너와 물리 플래너와 관련된 지표를 포함해요. 플래너는 논리 플랜을 생성하고, 물리 플래너는 논리 플랜에서 물리 플랜을 생성하는 역할을 담당해요.
ALL_OPTIMIZERS
| Description | 모든 옵티마이저 활성화 | | Type | double | | Query Node | ✅ |
CUMULATIVE_OPTIMIZER_TIMING
| Description | 모든 옵티마이저에 소요된 시간 | | Type | double | | Unit | milliseconds | | Query Node | ✅ | | Cumulative | ✅ |
PHYSICAL_PLANNER
| Description | 물리 플랜 생성에 소요된 시간 | | Type | double | | Unit | milliseconds | | Query Node | ✅ |
PHYSICAL_PLANNER_COLUMN_BINDING
| Description | 논리 플랜의 컬럼을 물리 컬럼에 바인딩하는 데 소요된 시간 | | Type | double | | Unit | milliseconds | | Query Node | ✅ |
PHYSICAL_PLANNER_CREATE_PLAN
| Description | 물리 플랜 생성에 소요된 시간 | | Type | double | | Unit | milliseconds | | Query Node | ✅ |
PHYSICAL_PLANNER_RESOLVE_TYPES
| Description | 논리 플랜의 타입을 물리 타입으로 해석하는 데 소요된 시간 | | Type | double | | Unit | milliseconds | | Query Node | ✅ |
PLANNER
| Description | 파싱된 SQL 노드에서 논리 플랜을 생성하는 시간. | | Type | double | | Unit | milliseconds | | Query Node | ✅ |
PLANNER_BINDING
| Description | 논리 플랜을 바인딩하는 데 걸린 시간. | | Type | double | | Unit | milliseconds | | Query Node | ✅ |
옵티마이저 지표 (Optimizer Metrics)
옵티마이저 지표는 QUERY_ROOT 수준에 있으며, 각 옵티마이저가 소요한 시간을 측정해요. 이 지표들은 특정 옵티마이저가 활성화되어 있을 때만 사용할 수 있어요. 사용 가능한 최적화는 duckdb_optimizers() 테이블 함수로 조회할 수 있어요.
각 옵티마이저에는 OPTIMIZER_⟨OPTIMIZER_NAME⟩ 템플릿을 따르는 해당 지표가 있어요. 예를 들어 OPTIMIZER_JOIN_ORDER 지표는 JOIN_ORDER 옵티마이저에 해당해요.
추가로 옵티마이저 지표를 지원하는 다음 지표가 있어요.
누적 지표 (Cumulative Metrics)
DuckDB는 모든 노드에서 사용할 수 있는 여러 누적 지표도 지원해요. QUERY_ROOT 노드에서는 이 지표들이 쿼리의 모든 연산자에 걸친 해당 지표의 합을 나타내요. OPERATOR 노드는 연산자의 특정 지표와 해당 자식 노드들의 합을 재귀적으로 나타내요.
이 누적 지표들은 기저의 특정 지표가 비활성화되어 있어도 독립적으로 활성화할 수 있어요.
사용 가능한 누적 지표 목록은 다음과 같아요.
예시 (Examples)
다음 예시들은 커스텀 프로파일링을 활성화하고 출력 형식을 json으로 설정하는 방법을 보여줘요. 첫 번째 예시에서는 프로파일링을 활성화하고 출력을 파일로 설정해요. EXTRA_INFO, OPERATOR_CARDINALITY, OPERATOR_TIMING만 활성화해요.
CREATE TABLE students (name VARCHAR, sid INTEGER);
CREATE TABLE exams (eid INTEGER, subject VARCHAR, sid INTEGER);
INSERT INTO students VALUES ('Mark', 1), ('Joe', 2), ('Matthew', 3);
INSERT INTO exams VALUES (10, 'Physics', 1), (20, 'Chemistry', 2), (30, 'Literature', 3);
PRAGMA enable_profiling = 'json';
PRAGMA profiling_output = '/path/to/file.json';
PRAGMA configure_profiling = '{"CPU_TIME": "false", "EXTRA_INFO": "true", "OPERATOR_CARDINALITY": "true", "OPERATOR_TIMING": "true"}';
SELECT name
FROM students
JOIN exams USING (sid)
WHERE name LIKE 'Ma%';
쿼리 실행 후 파일 내용:
{
"extra_info": {},
"query_name": "SELECT name\nFROM students\nJOIN exams USING (sid)\nWHERE name LIKE 'Ma%';",
"children": [
{
"operator_timing": 0.000001,
"operator_cardinality": 2,
"operator_type": "PROJECTION",
"extra_info": {
"Projections": "name",
"Estimated Cardinality": "1"
},
"children": [
{
"extra_info": {
"Join Type": "INNER",
"Conditions": "sid = sid",
"Build Min": "1",
"Build Max": "3",
"Estimated Cardinality": "1"
},
"operator_cardinality": 2,
"operator_type": "HASH_JOIN",
"operator_timing": 0.00023899999999999998,
"children": [
...
두 번째 예시는 출력에 상세 지표를 추가해요.
PRAGMA profiling_mode = 'detailed';
SELECT name
FROM students
JOIN exams USING (sid)
WHERE name LIKE 'Ma%';
출력 파일 내용:
{
"all_optimizers": 0.001413,
"cumulative_optimizer_timing": 0.0014120000000000003,
"planner": 0.000873,
"planner_binding": 0.000869,
"physical_planner": 0.000236,
"physical_planner_column_binding": 0.000005,
"physical_planner_resolve_types": 0.000001,
"physical_planner_create_plan": 0.000226,
"optimizer_expression_rewriter": 0.000029,
"optimizer_filter_pullup": 0.000002,
"optimizer_filter_pushdown": 0.000102,
...
"optimizer_column_lifetime": 0.000009999999999999999,
"rows_returned": 2,
"latency": 0.003708,
"cumulative_rows_scanned": 6,
"cumulative_cardinality": 11,
"extra_info": {},
"cpu_time": 0.000095,
"optimizer_build_side_probe_side": 0.000017,
"result_set_size": 32,
"blocked_thread_time": 0.0,
"query_name": "SELECT name\nFROM students\nJOIN exams USING (sid)\nWHERE name LIKE 'Ma%';",
"children": [
{
"operator_timing": 0.000001,
"operator_rows_scanned": 0,
"cumulative_rows_scanned": 6,
"operator_cardinality": 2,
"operator_type": "PROJECTION",
"cumulative_cardinality": 11,
"extra_info": {
"Projections": "name",
"Estimated Cardinality": "1"
},
"result_set_size": 32,
"cpu_time": 0.000095,
"children": [
...