QuackDB.Profile (quackdb v0.5.3)

Copy Markdown View Source

DuckDB query profiling helpers.

analyze/4 runs EXPLAIN (ANALYZE, FORMAT json) and decodes DuckDB's profile with Elixir's built-in JSON.decode/3. Known DuckDB profile keys are decoded with String.to_existing_atom/1 and loaded into structs. DuckDB's open-ended extra_info maps keep their own keys.

Use flatten/1, slowest/2, and report/2 when you want a profiler-style operator view.

Summary

Types

A flattened DuckDB operator row with its tree path and timing share.

t()

Functions

Runs EXPLAIN (ANALYZE, FORMAT json) and returns a decoded DuckDB query profile.

Runs EXPLAIN (ANALYZE, FORMAT json) and returns a decoded DuckDB query profile, raising on errors.

Runs EXPLAIN (FORMAT json) and returns a decoded DuckDB plan profile.

Runs EXPLAIN (FORMAT json) and returns a decoded DuckDB plan profile, raising on errors.

Converts DuckDB's profile tree into profiler-style operator rows.

Formats a compact text report for humans.

Returns the slowest operators by operator_timing.

Types

operator_row()

@type operator_row() :: %{
  path: [non_neg_integer()],
  name: String.t() | nil,
  type: String.t() | nil,
  timing: number() | nil,
  timing_percent: float() | nil,
  cpu_time: number() | nil,
  cardinality: non_neg_integer() | nil,
  rows_scanned: non_neg_integer() | nil,
  cumulative_cardinality: non_neg_integer() | nil,
  cumulative_rows_scanned: non_neg_integer() | nil,
  result_set_size: non_neg_integer() | nil,
  extra_info: map()
}

A flattened DuckDB operator row with its tree path and timing share.

t()

@type t() :: %QuackDB.Profile{
  all_optimizers: term(),
  attach_load_storage_latency: term(),
  attach_replay_wal_latency: term(),
  blocked_thread_time: term(),
  checkpoint_latency: term(),
  children: [QuackDB.Profile.Operator.t()],
  commit_local_storage_latency: term(),
  cpu_time: number() | nil,
  cumulative_cardinality: non_neg_integer() | nil,
  cumulative_optimizer_timing: term(),
  cumulative_rows_scanned: non_neg_integer() | nil,
  extra_info: term(),
  latency: number() | nil,
  optimizers: map(),
  physical_planner: term(),
  physical_planner_column_binding: term(),
  physical_planner_create_plan: term(),
  physical_planner_resolve_types: term(),
  planner: term(),
  planner_binding: term(),
  query_name: String.t() | nil,
  result_set_size: non_neg_integer() | nil,
  rows_returned: non_neg_integer() | nil,
  system_peak_buffer_memory: term(),
  system_peak_temp_dir_size: term(),
  total_bytes_read: term(),
  total_bytes_written: term(),
  total_memory_allocated: term(),
  waiting_to_attach_latency: term(),
  wal_replay_entry_count: term(),
  write_to_wal_latency: term()
}

Functions

analyze(connection, statement, params \\ [], options \\ [])

@spec analyze(DBConnection.conn() | module(), iodata() | term(), [term()], keyword()) ::
  {:ok, t()} | {:error, Exception.t()}

Runs EXPLAIN (ANALYZE, FORMAT json) and returns a decoded DuckDB query profile.

analyze!(connection, statement, params \\ [], options \\ [])

@spec analyze!(DBConnection.conn() | module(), iodata() | term(), [term()], keyword()) ::
  t()

Runs EXPLAIN (ANALYZE, FORMAT json) and returns a decoded DuckDB query profile, raising on errors.

explain(connection, statement, params \\ [], options \\ [])

@spec explain(DBConnection.conn() | module(), iodata() | term(), [term()], keyword()) ::
  {:ok, t()} | {:error, Exception.t()}

Runs EXPLAIN (FORMAT json) and returns a decoded DuckDB plan profile.

explain!(connection, statement, params \\ [], options \\ [])

@spec explain!(DBConnection.conn() | module(), iodata() | term(), [term()], keyword()) ::
  t()

Runs EXPLAIN (FORMAT json) and returns a decoded DuckDB plan profile, raising on errors.

flatten(profile)

@spec flatten(t()) :: [operator_row()]

Converts DuckDB's profile tree into profiler-style operator rows.

report(profile, options \\ [])

@spec report(
  t(),
  keyword()
) :: String.t()

Formats a compact text report for humans.

slowest(profile, limit \\ 10)

@spec slowest(t(), pos_integer()) :: [operator_row()]

Returns the slowest operators by operator_timing.