Use EXPLAIN, PROFILE, and QUERY_HISTORY views to inspect plans, runtime metrics, and bottlenecks in Snowflake SQL statements.
List recent statements with SELECT query_id, total_elapsed_time, query_text FROM TABLE(INFORMATION_SCHEMA.QUERY_HISTORY()) ORDER BY total_elapsed_time DESC LIMIT 10;
. Copy the query_id
of the slowest query for deeper inspection.
QUERY_HISTORY shows elapsed times, bytes scanned, and cluster queuing. Join with QUERY_ACCELERATED_STATS or QUERY_STAGE_HISTORY to identify partitions skipped, spilled bytes, and skewed joins.
EXPLAIN
returns Snowflake’s plan without running the query. Inspect nodes for JOIN ORDER, PARTITION PRUNING, and FILTER placement to ensure predicates limit scanned data.
EXPLAIN [USING {TABULAR | JSON | TEXT}] <sql_statement>;
PROFILE
executes the statement and captures stage-level metrics—partition scans, bytes spilled, and compilation time. Use it after studying EXPLAIN
so you intentionally pay the extra run cost.
PROFILE <sql_statement>;
SELECT * FROM TABLE(INFORMATION_SCHEMA.QUERY_PROFILE('your_query_id'));
lists each stage’s execution and wait times. Target stages with a high percentage of total_elapsed_time for optimization.
Run ALTER SESSION SET QUERY_TAG='checkout_report_v3';
before execution. Later, filter QUERY_HISTORY WHERE query_tag='checkout_report_v3'
to isolate related runs.
Tag analytical queries, test complex CTEs individually, cluster large fact tables on high-cardinality columns, and save EXPLAIN
outputs in version control for future comparison.
Yes. PROFILE fully executes the query, so it uses compute resources and credits. Run it only after cheaper methods like EXPLAIN and plan inspection.
Yes, if you have the MONITOR privilege on their warehouse or the ACCOUNTADMIN role. Query ACCOUNT_USAGE views with the other user’s query_id
.
In the EXPLAIN output, check for Pruning=true flags and compare scan bytes in QUERY_STAGE_HISTORY. High unpruned bytes indicate missing filters or clustering.