Query Performance Profiler๏
Overview๏
Query Performance Profiler ืืื ืืื ื ืืืืจ ืืฉืืืืชืืช MongoDB ืืืืืืช, ืืืกืคืง:
ืืืืื ืฉืืืืชืืช ืืืืืืช โ ืืขืงื ืืืื ืืืช ืืืจื ืฉืืืืชืืช ืฉืืืจืืืช ืืกืฃ ืืื ืืืืืจ
ื ืืชืื Explain Plans โ ืืฆืื ืืืืืืืืช ืฉื ืชืืื ืืช ืืืืฆืืข ืฉื MongoDB (ืืืื Aggregation Pipelines)
ืืืืฆืืช ืืืคืืืืืืฆืื โ ืืฆืขืืช ืืืืืืืืืช ืืฉืืคืืจ ืืืฆืืขืื
ืืืกืืืจืืืช ืฉืืืืชืืช โ ืฉืืืจื ืื ืืชืื ืฉื ืืคืืกื ืฉืืืืชืืช ืืืืจื ืืื
ืงืื ืืขื๏
ืืคืจืืคืืืืจ ืืืืขื ื-Admin ืืืื. ืืืฉื ืืืื ืืืจืฉืช:
ืืจืฉืืช Admin ื-WebApp, ืื
ืืืงื ืืืขืืื (
X-Profiler-Token)
ืื ืืืื ืื ืขืืฉื๏
ืื ืืืืืฃ ืืช MongoDB Profiler ืืืืื ื ืืจืืช ื-DB
ืื ืืกืคืง ืืืคืืืืืืฆืื ืืืืืืืืช (ืจืง ืืืืฆืืช)
ืื ืืืืขื ื-Production Debugging ืืืื ืืืช ืฉื ืฉืืืืชืืช ืืืืืืช
ืืืฉืง ืืฉืชืืฉ (WebApp)๏
ืื ืชืื๏
GET /admin/profiler
ืืื ืืืืืข๏
ืืจื Settings โ ืืื ืืืืื โ Query Profiler
ืื ืืฉืืจืืช ืืืชืืืช
/admin/profiler
ืื ืจืืืื ืืืฉืืืจื๏
ืืืืจ |
ืชืืืืจ |
|---|---|
Summary |
ืกืืืื ืืืื: ืืกืคืจ ืฉืืืืชืืช ืืืืืืช, ืืื ืืืืฆืข, collections ืืืฉืคืขืื |
Slow Queries Table |
ืืืื ืขื ืฉืืืืชืืช ืืืืืืช, ืืืื ืกืื ืื ืืคื collection |
ื ืืชืื Query/Pipeline |
ืืืคืก ืืืื ืช ืฉืืืืชื ืื ืืชืื ืืืืื |
Explain Visualization |
ืืืืืืืืืฆืื ืฉื ืฉืืื ืืืืฆืืข (COLLSCAN, IXSCAN, FETCH ืืืโ) |
Recommendations |
ืืืืฆืืช ืืืคืืืืืืฆืื ืืคื ืืืืจื (ืงืจืืื/ืืืืจื/ืืืืข) |
Note
ืืจืืจืช ืืืืื ืฉื ื-verbosity ืืื queryPlanner (ืืืื) โ ืื ืืจืืฅ ืืช ืืฉืืืืชื ืืคืืขื.
API Reference๏
Authentication๏
ืื PROFILER_AUTH_TOKEN ืืืืืจ, ืืฉ ืืฉืืื ืืช ืืืืงื ืืืืชืจืช:
X-Profiler-Token: <your-token>
ืื ืืืืงื ืื ืืืืืจ, ืืืืฉื ืืชืืกืกืช ืขื ืืจืฉืืช Admin ื-WebApp Session.
Endpoints๏
Method |
Endpoint |
ืชืืืืจ |
|---|---|---|
GET |
|
ืกืืืื ืืฆื ืืคืจืืคืืืืจ |
GET |
|
ืจืฉืืืช ืฉืืืืชืืช ืืืืืืช (ืขื ืกืื ืื) |
POST |
|
ืืจืฆืช Explain Plan ืขื ืฉืืืืชื/pipeline |
POST |
|
ื ืืชืื ืืืืืฆืืช ืืฉืืืืชื |
POST |
|
Alias ื-recommendations |
GET |
|
ืกืืืืกืืืงืืช collection (ืืืื, ืืื ืืงืกืื) |
GET /api/profiler/summary๏
ืืืืืจ ืกืืืื ืืืื:
curl -H "X-Profiler-Token: $TOKEN" \
https://your-app.com/api/profiler/summary
Response:
{
"status": "success",
"data": {
"total_slow_queries": 42,
"collections_affected": ["code_snippets", "users"],
"avg_execution_time_ms": 350.5,
"max_execution_time_ms": 2500.0,
"unique_patterns": 15,
"threshold_ms": 100
}
}
GET /api/profiler/slow-queries๏
Query Parameters:
Parameter |
ืชืืืืจ |
ืืจืืจืช ืืืื |
|---|---|---|
|
ืืกืคืจ ืฉืืืืชืืช ืืืืืืจ |
|
|
ืกืื ืื ืืคื collection |
(ืืื) |
|
ืืื ืืืฆืืข ืืื ืืืื (ms) |
(ืืื) |
|
ืฉืืืืชืืช ืืืฉืขืืช ืืืืจืื ืืช |
(ืืื) |
ืืืืื:
curl -H "X-Profiler-Token: $TOKEN" \
"https://your-app.com/api/profiler/slow-queries?limit=20&collection=code_snippets&hours=24"
POST /api/profiler/explain๏
ืืจืืฅ Explain Plan ืขื ืฉืืืืชื ืื Aggregation Pipeline.
Body (Query):
{
"collection": "code_snippets",
"query": {"user_id": "123", "is_deleted": false},
"verbosity": "queryPlanner"
}
Body (Pipeline):
{
"collection": "code_snippets",
"pipeline": [
{"$match": {"user_id": "123"}},
{"$group": {"_id": "$language", "count": {"$sum": 1}}}
],
"verbosity": "queryPlanner"
}
ืืืืื:
curl -X POST \
-H "X-Profiler-Token: $TOKEN" \
-H "Content-Type: application/json" \
-d '{"collection":"code_snippets","query":{"user_id":"<value>"}}' \
https://your-app.com/api/profiler/explain
POST /api/profiler/recommendations๏
ืืืืืจ Explain Plan + ืืืืฆืืช ืืืคืืืืืืฆืื:
curl -X POST \
-H "X-Profiler-Token: $TOKEN" \
-H "Content-Type: application/json" \
-d '{"collection":"code_snippets","query":{"user_id":"<value>"}}' \
https://your-app.com/api/profiler/recommendations
GET /api/profiler/collection/<name>/stats๏
ืืืืืจ ืกืืืืกืืืงืืช collection:
curl -H "X-Profiler-Token: $TOKEN" \
https://your-app.com/api/profiler/collection/code_snippets/stats
Response:
{
"status": "success",
"data": {
"size_bytes": 1048576,
"count": 5000,
"avg_obj_size": 210,
"index_count": 3,
"indexes": ["_id_", "user_id_1", "user_id_1_is_deleted_1"],
"total_index_size": 524288
}
}
Security๏
Authentication๏
ืฉืืื |
ืืฉืชื ื/ืื ืื ืื |
ืชืืืืจ |
|---|---|---|
Token |
|
ืืืงื ื ืฉืื ื-Header |
IP Allowlist |
|
ืจืฉืืืช IPs ืืืจืฉืื (CSV) |
Rate Limit |
|
ืืืืืช ืืงืฉืืช ืืืงื (ืืจืืจืช ืืืื: 60) |
Admin Session |
WebApp |
ืื ืืื Token, ื ืืจืฉืช ืืจืฉืืช Admin |
ืืืืจืช Token๏
# .env
PROFILER_AUTH_TOKEN=my-secure-profiler-token
PROFILER_ALLOWED_IPS=127.0.0.1,10.0.0.1
ืืืืจืช Observer Effect๏
Warning
Observer Effect โ ืืจืฆืช explain("executionStats") ืื explain("allPlansExecution") ืืจืืฆื ืืช ืืฉืืืืชื ืืคืืขื!
ืืกืืืื ืื:
ืื ืืฉืืืืชื ืืืืืช ืื ืืื ืืขืืืกื ืขื ื-CPU, ืืจืฆืช ื-Explain ืชืืคืื ืืช ืืขืืืก
ืื ืืฉืืืืชื ื ืืขืืช ืืกืืืื (write operations), ืื ืขืืื ืืืืืืจ ืืช ืืืฆื
ื-Production ืขืืืก, ืืจืฆื ืืืืืืืืช ืฉื explain ืืืืื ืืืฆืืจ โืืคืงื ืฉืืโ
ืืืืฆืืช:
ืืฉืชืืฉ ื-``queryPlanner`` ืืืจืืจืช ืืืื โ ืื ืืจืืฅ ืืช ืืฉืืืืชื, ืจืง ืืฆืื ืืช ืืชืืื ืืช
ืืจืฅ ``executionStats`` ืจืง ืืคื ืืจืืฉื โ ืืคื ืฉืืืืืฉ ืืืคืชืืจ โื ืชืโ ืืืฉืืืจื
ืื ืชืจืืฅ explain ืืืืืืืืช ืืื ืฉืืืืชื ืืืืืช โ ืื ืืืคืื ืืช ืืืขืื
ืฉืงืื ืืจืฆืช explain ืืฉืขืืช ืฉืคื ืื ืขื replica secondary
ืจืื |
ืชืืืืจ |
ืืชื ืืืฉืชืืฉ |
|---|---|---|
|
ืชืืื ืืช ืืืื, ืืื ืืจืฆื |
ืืืืืงืช ืืื ืืงืกืื (ืืืื) |
|
ืืืื ืกืืืืกืืืงืืช ืืืฆืืข |
ื ืืชืื ืืืฆืืขืื ืืื |
|
ืื ืืชืืื ืืืช ืฉื ืืื ื |
Debug ืืชืงืื ืืืื |
Privacy / PII๏
Important
ื ืจืืื ืฉืืืืชืืช ืืื ืข ืืืืคืช ืืืืข ืืืฉื (PII)
ืืคืื ืงืฆืื _normalize_query_shape ืืืืืคื ืืช ืื ืืขืจืืื ืืคืืืืกืืืืืจืื:
ืขืจืืื ืคืฉืืืื โ
<value>ืืขืจืืื โ
<N items>null โ
<null>
ืืืืื:
# Query ืืงืืจื (ืื ืืืฆื)
{"email": "john@example.com", "status": {"$in": ["active", "pending"]}}
# Query ืื ืืจืื (ืื ืฉืืืฆื ืืืฉืืืจื)
{"email": "<value>", "status": {"$in": ["<2 items>"]}}
Warning
ืื ืชืชืขื ืื ืชืฆืื ืืืืืืืช ืขื ื ืชืื ื ืืืช/PII ืืืืืืช ืื ืืืืืื.
Persistence๏
Collection๏
ืฉื: slow_queries_log
TTL Index๏
ืืืืงื ืืืืืืืืช ืืืจื 7 ืืืื:
db.slow_queries_log.createIndex(
{"timestamp": 1},
{expireAfterSeconds: 604800, name: "ttl_cleanup"}
)
ืืื ืืงืกืื ื ืืกืคืื๏
// ืืืคืืฉ ืืืืจ ืืคื collection + ืืื
db.slow_queries_log.createIndex(
{"collection": 1, "timestamp": -1},
{name: "collection_timestamp"}
)
// ืืืคืืฉ ืืคื ืืคืืก ืฉืืืืชื
db.slow_queries_log.createIndex(
{"query_id": 1},
{name: "query_pattern"}
)
Metrics (Prometheus)๏
ืืืจืืงืืช ืืืื ืืช ืืืฉืจ PROFILER_METRICS_ENABLED=true:
Metric |
Type |
ืชืืืืจ |
|---|---|---|
|
Counter |
ืืกืคืจ ืฉืืืืชืืช ืืืืืืช ืืคื collection ื-operation |
|
Histogram |
ืืชืคืืืืช ืืื ื ืฉืืืืชืืช |
|
Counter |
ืืกืคืจ COLLSCAN ืฉืืืื |
|
Gauge |
ืืกืคืจ ืฉืืืืชืืช ืืืืคืจ ืืืืืจืื |
Environment Variables๏
ืจืื ืืช ืืืืื ืืืืื ื-ืืฉืชื ื ืกืืืื - ืจืคืจื ืก.
ืืฉืชื ื |
ืชืืืืจ |
ืืจืืจืช ืืืื |
|---|---|---|
|
ืืคืขืืช Query Performance Profiler |
|
|
ืกืฃ ืืื (ms) ืืืืืจืช โืฉืืืืชื ืืืืืชโ |
|
|
ืืกืคืจ ืฉืืืืชืืช ืืืืืจืื |
|
|
ืืืงื ืืืฉื (Header |
(ืจืืง) |
|
Allowlist ืฉื IPs (CSV) |
(ืจืืง) |
|
ืืืืืช ืืงืฉืืช ืืืงื |
|
|
ืืคืขืืช ืืืจืืงืืช Prometheus |
|
ืืืืฆืืช ืืืคืืืืืืฆืื ื ืคืืฆืืช๏
ืืขืื |
ืกืืืคืืื |
ืืืืฆื |
|---|---|---|
๐ด COLLSCAN |
|
ืฆืืจ ืืื ืืงืก ืขื ืฉืืืช ืืกืื ืื |
๐ Sort ืืืืืจืื |
|
ืืืกืฃ ืฉืื ืืืื ืืืื ืืงืก |
๐ก ืืืก ืืขืืืืช ื ืืื |
|
ืฉืคืจ selectivity ืฉื ืืืื ืืงืก |
๐ด $lookup ืืื ืืื ืืงืก |
|
ืฆืืจ ืืื ืืงืก ืขื ื-foreign field |
๐ $sort ืืฉืชืืฉ ืืืืกืง |
|
ืืืกืฃ $match ืืคื ื ื-$sort |
ืงืืฉืืจืื ื ืืกืคืื๏
ืืฉืชื ื ืกืืืื - ืจืคืจื ืก โ ืืืืช ืืฉืชื ื ืกืืืื ืืืื
๐ก Observability Dashboard & API โ ืืฉืืืจื Observability
Background Jobs Monitor โ ืืื ืืืืจ Jobs