# Profiling

TideORM exposes two different profiling tools:

- `GlobalProfiler` for lightweight application-wide query timing and slow-query counters.
- `Profiler` for manual profiling sessions where you want to build a detailed `ProfileReport` yourself.

Use `GlobalProfiler` when you want to observe real query execution with minimal setup. Use `Profiler` when you want to capture custom SQL strings, table names, row counts, and run `QueryAnalyzer` over a curated set of queries.

## Global Profiling

`GlobalProfiler` records aggregate timing data for real executed queries when it is enabled.

```rust
use tideorm::prelude::*;
use tideorm::profiling::GlobalProfiler;

GlobalProfiler::enable();
GlobalProfiler::reset();
GlobalProfiler::set_slow_threshold(200);

let users = User::query()
    .where_eq("active", true)
    .limit(25)
    .get()
    .await?;

let stats = GlobalProfiler::stats();
println!("{}", stats);

GlobalProfiler::disable();
```

When enabled, TideORM records query timings from the main execution paths:

- query-builder reads and counts routed through the database helpers
- raw SQL helpers such as `Database::raw`, `Database::execute`, and JSON/raw parameterized helpers
- direct CRUD methods generated by the `Model` derive such as `find`, `save`, `update`, `delete`, and `destroy`
- aggregate helpers such as `count_distinct`, `sum`, `avg`, `min`, and `max`
- full-text search execution paths
- internal executor paths used by batch and model helpers

`GlobalStats` exposes:

- `total_queries`
- `total_time()`
- `avg_query_time()`
- `slow_queries`
- `slow_percentage()`

## What Global Profiling Does Not Capture

`GlobalProfiler` is intentionally lightweight. It tracks counts and durations, but it does not retain SQL text or per-query metadata.

If you need a detailed report with SQL strings, operation types, slowest queries, table counts, or custom annotations, build that report manually with `Profiler` and `ProfiledQuery`.

## Manual Profile Reports

`Profiler` is a report builder. It does not automatically subscribe to all TideORM queries by itself.

```rust
use std::time::Duration;
use tideorm::profiling::{ProfiledQuery, Profiler};

let mut profiler = Profiler::start();

profiler.record("SELECT * FROM users WHERE active = true", Duration::from_millis(12));

profiler.record_full(
    ProfiledQuery::new("SELECT * FROM posts WHERE user_id = 42", Duration::from_millis(37))
        .with_table("posts")
        .with_rows(8),
);

let report = profiler.stop();
println!("{}", report);
```

This is useful when you are instrumenting a benchmark, comparing alternative query shapes, or building a focused performance report in tests.

## Query Analysis

`QueryAnalyzer` can inspect SQL and return optimization suggestions.

```rust
use tideorm::profiling::QueryAnalyzer;

let suggestions = QueryAnalyzer::analyze("SELECT * FROM users WHERE email = 'john@example.com'");

for suggestion in suggestions {
    println!("{}", suggestion);
}
```

Use this alongside `Profiler` when you want human-readable guidance about indexing, query shape, and complexity.

## Related Features

- Query logging is covered in [Queries](queries.md).
- Slow-query thresholds for logs and profiler statistics are separate settings.
- The global profiler is process-wide, so reset it between tests when you need deterministic assertions.