지표 및 분석 (Metrics and analytics)
D1은 쿼리 볼륨, 쿼리 지연 시간, 저장 용량을 계정의 전체 및/또는 개별 데이터베이스 단위로 살펴볼 수 있는 데이터베이스 분석을 제공해요.
출처: 문서
본문
Cloudflare 대시보드 차트에 표시되는 지표는 Cloudflare의 GraphQL Analytics API에서 쿼리해요. GraphQL이나 HTTP 클라이언트를 통해 이 지표들을 프로그래밍 방식으로 접근할 수 있어요.
지표 (Metrics)
D1은 현재 다음 지표를 내보내요:
| 지표 | GraphQL 필드 이름 | 설명 | | Read Queries (qps) | readQueries | 데이터베이스에 대해 실행된 읽기 쿼리 수. 청구에 사용되지 않는 원시 읽기 쿼리 수예요. | | Write Queries (qps) | writeQueries | 데이터베이스에 대해 실행된 쓰기 쿼리 수. 청구에 사용되지 않는 원시 쓰기 쿼리 수예요. | | Rows read (count) | rowsRead | 쿼리 전체에서 읽은(스캔한) 행 수. 행이 어떻게 계산되는지에 대한 자세한 내용은 Pricing 문서를 참고하세요. | | Rows written (count) | rowsWritten | 쿼리 전체에서 쓴 행 수. | | Query Response (bytes) | queryBatchResponseBytes | 직렬화된 쿼리 응답의 총 응답 크기. 모든/어떤 열 이름, 행, 메타데이터를 포함해요. 바이트 단위로 보고돼요. | | Query Latency (ms) | queryBatchTimeMs | 서버 측 총 쿼리 응답 시간. 응답 직렬화를 포함해요. 밀리초 단위로 보고돼요. | | Storage (Bytes) | databaseSizeBytes | 데이터베이스의 최대 크기. 바이트 단위로 보고돼요. |
지표는 지난 31일 동안 쿼리할 수 있고(그리고 보관되며) 유지돼요.
행 수 (Row counts)
D1은 Workers Binding API를 통해 개별 쿼리에 대한 응답으로 읽은 행 수, 쓴 행 수(또는 둘 다)를 반환해요.
행 수는 해당 쿼리가 읽은(스캔한) 또는 쓴 행이 정확히 몇 개인지에 대한 정밀한 수예요. 행 수를 살펴보면 특정 쿼리의 성능과 비용을 이해할 수 있어요. 인덱스를 사용해 읽는 행을 줄일 수 있는지도 파악할 수 있죠. 쿼리 수를 살펴보면 데이터베이스에 대한 전체 트래픽 볼륨을 이해하고, 어떤 데이터베이스가 활발히 사용 중인지도 가려낼 수 있어요.
행이 어떻게 계산되는지에 대한 자세한 내용은 Pricing 문서를 참고하세요.
대시보드에서 지표 보기
D1에 대한 데이터베이스별 분석은 Cloudflare 대시보드에서 제공돼요. 데이터베이스의 현재 및 과거 지표를 보려면:
-
Cloudflare 대시보드에서 D1 페이지로 이동해요.
-
기존 D1 데이터베이스를 선택해요.
-
Metrics 탭을 선택해요.
선택적으로 시간 범위를 지정해 쿼리할 수 있어요. 기본값은 지난 24시간이에요.
GraphQL API로 쿼리하기
GraphQL Analytics API를 통해 D1 데이터베이스의 분석을 프로그래밍 방식으로 쿼리할 수 있어요. 이 API는 Cloudflare 대시보드와 동일한 데이터셋을 쿼리하며, GraphQL 인트로스펙션(introspection)을 지원해요.
D1의 GraphQL 데이터셋은 Cloudflare 계정 ID와 함께 accountTag 필터를 요구하며 다음을 포함해요:
-
d1AnalyticsAdaptiveGroups -
d1StorageAdaptiveGroups -
d1QueriesAdaptiveGroups
예시 (Examples)
주어진 $databaseId에 대해 readQueries, writeQueries의 합계를 databaseId와 date로 그룹화해 쿼리하려면:
query D1ObservabilitySampleQuery(
$accountTag: string!
$start: Date
$end: Date
$databaseId: string
) {
viewer {
accounts(filter: { accountTag: $accountTag }) {
d1AnalyticsAdaptiveGroups(
limit: 10000
filter: { date_geq: $start, date_leq: $end, databaseId: $databaseId }
orderBy: [date_DESC]
) {
sum {
readQueries
writeQueries
}
dimensions {
date
databaseId
}
}
}
}
}
데이터베이스별 평균 queryBatchTimeMs와 90번째 백분위수 queryBatchTimeMs를 둘 다 쿼리하려면:
query D1ObservabilitySampleQuery2(
$accountTag: string!
$start: Date
$end: Date
$databaseId: string
) {
viewer {
accounts(filter: { accountTag: $accountId }) {
d1AnalyticsAdaptiveGroups(
limit: 10000
filter: { date_geq: $start, date_leq: $end, databaseId: $databaseId }
orderBy: [date_DESC]
) {
quantiles {
queryBatchTimeMsP90
}
dimensions {
date
databaseId
}
}
}
}
}
계정 전체의 readQueries와 writeQueries를 쿼리하려면:
query D1ObservabilitySampleQuery3(
$accountTag: string!
$start: Date
$end: Date
$databaseId: string
) {
viewer {
accounts(filter: { accountTag: $accountTag }) {
d1AnalyticsAdaptiveGroups(
limit: 10000
filter: { date_geq: $start, date_leq: $end, databaseId: $databaseId }
) {
sum {
readQueries
writeQueries
}
}
}
}
}
insights 쿼리하기
D1은 쿼리 성능을 이해하고 디버깅할 수 있는 지표를 제공해요. GraphQL의 d1QueriesAdaptiveGroups나 wrangler d1 insights 명령어로 접근할 수 있어요.
D1은 쿼리 실행 간 지표를 더 쉽게 분석할 수 있도록 쿼리 문자열을 캡처해요. 민감한 정보를 제거하기 위해 바인딩된 파라미터(Bound parameters)는 캡처하지 않아요.
| 옵션 | 설명 | | --timePeriod | 지금부터 제공된 기간까지의 데이터를 가져옴 (기본값: 1d). | | --sort-type | insights를 정렬할 기준 연산. sum과 avg 중 선택 (기본값: sum). | | --sort-by | insights를 정렬할 기준 필드. time, reads, writes, count 중 선택 (기본값: time). | | --sort-direction | 정렬 방향. ASC와 DESC 중 선택 (기본값: DESC). | | --json | 결과를 깨끗한 JSON으로 반환할지 여부를 나타내는 불리언 값 (기본값: false). | | --limit | 가져올 최대 쿼리 수. |
실행 횟수 기준 상위 3개 쿼리를 찾으려면:
npx wrangler d1 insights <database_name> --sort-type=sum --sort-by=count --limit=3
⛅️ wrangler 3.95.0
-------------------
-------------------
🚧 `wrangler d1 insights` is an experimental command.
🚧 Flags for this command, their descriptions, and output may change between wrangler versions.
-------------------
[
{
"query": "SELECT tbl_name as name,\n (SELECT ncol FROM pragma_table_list(tbl_name)) as num_columns\n FROM sqlite_master\n WHERE TYPE = \"table\"\n AND tbl_name NOT LIKE \"sqlite_%\"\n AND tbl_name NOT LIKE \"d1_%\"\n AND tbl_name NOT LIKE \"_cf_%\"\n ORDER BY tbl_name ASC;",
"avgRowsRead": 2,
"totalRowsRead": 4,
"avgRowsWritten": 0,
"totalRowsWritten": 0,
"avgDurationMs": 0.49505,
"totalDurationMs": 0.9901,
"numberOfTimesRun": 2,
"queryEfficiency": 0
},
{
"query": "SELECT * FROM Customers",
"avgRowsRead": 4,
"totalRowsRead": 4,
"avgRowsWritten": 0,
"totalRowsWritten": 0,
"avgDurationMs": 0.1873,
"totalDurationMs": 0.1873,
"numberOfTimesRun": 1,
"queryEfficiency": 1
},
{
"query": "SELECT * From Customers",
"avgRowsRead": 0,
"totalRowsRead": 0,
"avgRowsWritten": 0,
"totalRowsWritten": 0,
"avgDurationMs": 1.0225,
"totalDurationMs": 1.0225,
"numberOfTimesRun": 1,
"queryEfficiency": 0
}
]
평균 실행 시간 기준 상위 3개 쿼리를 찾으려면:
npx wrangler d1 insights <database_name> --sort-type=avg --sort-by=time --limit=3
⛅️ wrangler 3.95.0
-------------------
-------------------
🚧 `wrangler d1 insights` is an experimental command.
🚧 Flags for this command, their descriptions, and output may change between wrangler versions.
-------------------
[
{
"query": "SELECT * From Customers",
"avgRowsRead": 0,
"totalRowsRead": 0,
"avgRowsWritten": 0,
"totalRowsWritten": 0,
"avgDurationMs": 1.0225,
"totalDurationMs": 1.0225,
"numberOfTimesRun": 1,
"queryEfficiency": 0
},
{
"query": "SELECT tbl_name as name,\n (SELECT ncol FROM pragma_table_list(tbl_name)) as num_columns\n FROM sqlite_master\n WHERE TYPE = \"table\"\n AND tbl_name NOT LIKE \"sqlite_%\"\n AND tbl_name NOT LIKE \"d1_%\"\n AND tbl_name NOT LIKE \"_cf_%\"\n ORDER BY tbl_name ASC;",
"avgRowsRead": 2,
"totalRowsRead": 4,
"avgRowsWritten": 0,
"totalRowsWritten": 0,
"avgDurationMs": 0.49505,
"totalDurationMs": 0.9901,
"numberOfTimesRun": 2,
"queryEfficiency": 0
},
{
"query": "SELECT * FROM Customers",
"avgRowsRead": 4,
"totalRowsRead": 4,
"avgRowsWritten": 0,
"totalRowsWritten": 0,
"avgDurationMs": 0.1873,
"totalDurationMs": 0.1873,
"numberOfTimesRun": 1,
"queryEfficiency": 1
}
]
지난 7일 동안 행을 가장 많이 쓴 상위 10개 쿼리를 찾으려면:
npx wrangler d1 insights <database_name> --sort-type=sum --sort-by=writes --limit=10 --timePeriod=7d
⛅️ wrangler 3.95.0
-------------------
-------------------
🚧 `wrangler d1 insights` is an experimental command.
🚧 Flags for this command, their descriptions, and output may change between wrangler versions.
-------------------
[
{
"query": "SELECT * FROM Customers",
"avgRowsRead": 4,
"totalRowsRead": 4,
"avgRowsWritten": 0,
"totalRowsWritten": 0,
"avgDurationMs": 0.1873,
"totalDurationMs": 0.1873,
"numberOfTimesRun": 1,
"queryEfficiency": 1
},
{
"query": "SELECT * From Customers",
"avgRowsRead": 0,
"totalRowsRead": 0,
"avgRowsWritten": 0,
"totalRowsWritten": 0,
"avgDurationMs": 1.0225,
"totalDurationMs": 1.0225,
"numberOfTimesRun": 1,
"queryEfficiency": 0
},
{
"query": "SELECT tbl_name as name,\n (SELECT ncol FROM pragma_table_list(tbl_name)) as num_columns\n FROM sqlite_master\n WHERE TYPE = \"table\"\n AND tbl_name NOT LIKE \"sqlite_%\"\n AND tbl_name NOT LIKE \"d1_%\"\n AND tbl_name NOT LIKE \"_cf_%\"\n ORDER BY tbl_name ASC;",
"avgRowsRead": 2,
"totalRowsRead": 4,
"avgRowsWritten": 0,
"totalRowsWritten": 0,
"avgDurationMs": 0.49505,
"totalDurationMs": 0.9901,
"numberOfTimesRun": 2,
"queryEfficiency": 0
}
]