Skip to content

EXPLAIN scoring

Every EXPLAIN analysis in tdfs4ds returns four signals side by side. The first two are LLM-assessed scores; the last two are deterministic counters parsed from the raw EXPLAIN text.

Key Type Source Meaning
user_score 1–5 int LLM, after [You]-item validation SQL quality — what the author controls
global_score 1–5 int LLM Overall plan quality including infrastructure factors
n_steps int Regex on raw EXPLAIN Numbered execution steps (plan depth)
n_spool_objects int Regex on raw EXPLAIN Distinct Spool N objects referenced (intermediate materialisation count)

All four are stored in FS_PROCESS_DOCUMENTATION_EXPLAIN and returned via retrieve_explain_documentation() / get_process_info() as USER_SCORE, OPTIMIZATION_SCORE, EXPLAIN_N_STEPS, EXPLAIN_N_SPOOL_OBJECTS.

Why two scores

Score What it answers
user_score "How good is the SQL itself? Is the data scientist writing efficient queries?"
global_score "How good is the execution plan? Is the database tuned for this workload?"

A user_score = 5 with global_score = 2 means the SQL is well written but the underlying tables need a DBA action (Primary Index re-design, stats collection, partitioning). A user_score = 2 is the data scientist's problem — try the query optimizer.

Why two counters

The counters complement the scores by giving you deterministic evidence:

  • n_steps — fewer steps usually means less work. Halving the number of steps is a strong signal that a rewrite paid off.
  • n_spool_objects — fewer spools means less intermediate materialisation (a proxy for memory + IO).

Both come from a regex on the raw EXPLAIN text — they are not opinions, so they are useful as a sanity check on the LLM scores.

Helper functions

from tdfs4ds.genai import (
    document_sql_query_explain,
    _parse_explain_metrics,
    _parse_explain_signals,
)

scored = document_sql_query_explain(sql_query="SELECT ...", classify=True)
# {
#     'explanation':    '...',
#     'user_score':     4,
#     'global_score':   3,
#     'n_steps':        9,
#     'n_spool_objects':4,
#     'warnings':       ['...'],
#     'recommendations':['[You] ...', '[DBA] ...'],
# }

# Pure deterministic counters (no LLM)
metrics = _parse_explain_metrics(scored['raw_plan'])
# {'n_steps': 9, 'n_spool_objects': 4}

# Ground-truth booleans + scan counts
signals = _parse_explain_signals(scored['raw_plan'])
# {
#   'has_product_join':     False,
#   'table_scan_counts':    {'TRANSACTIONS': 1},
#   'has_duplicate_scans':  False,
#   'has_redistribution':   True,
# }

document_sql_query_explain(classify=False) keeps raw [You] items as flagged by the LLM. Use classify=True to filter out false positives like uncorrelated scalar subqueries that Teradata evaluates once.

Schema migration on upgrade

The columns USER_SCORE, N_STEPS, and N_SPOOL_OBJECTS were added in v0.2.9. On upgrade, documentation_tables_creation() and migrate_documentation_explain_schema() add them idempotently — a SHOW TABLE probe runs first. Older rows read back as NULL until re-documented; retrieve_explain_documentation() probes the live DDL and only selects the new columns when present, so the call works on un-migrated installs.

Visual flow diagram

For interactive HTML flow diagrams of any raw EXPLAIN output — including ones not coming from a registered tdfs4ds process — use the td-explain skill.