Snowflake's QUERY_HISTORY exposes detailed execution statistics for every query, making it essential for performance analysis, bottleneck identification, and cost optimization. There are two ways to retrieve it — the INFORMATION_SCHEMA table function and the ACCOUNT_USAGE view — and they differ in latency, retention, and permission model.
QUERY_HISTORY has two retrieval points. The exam asks about the differences precisely, so make sure the comparison below is locked in.
| Dimension | INFORMATION_SCHEMA.QUERY_HISTORY() | ACCOUNT_USAGE.QUERY_HISTORY |
|---|---|---|
| Type | Table function | View |
| Retention | Last 7 days | 365 days |
| Data latency | None (real-time) | Up to 45 minutes |
| Max rows | 10,000 (RESULT_LIMIT) | No limit |
| Scope | Queries visible to the current role | Every query in the account |
| Required privilege | None special (within role scope) | IMPORTED PRIVILEGES on the SNOWFLAKE DB |
| How to call | SELECT * FROM TABLE(INFORMATION_SCHEMA.QUERY_HISTORY(...)) | SELECT * FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY |
Call it as a table function and filter by time range or user with named parameters.
-- Query history from the last hour
SELECT *
FROM TABLE(INFORMATION_SCHEMA.QUERY_HISTORY(
DATE_RANGE_START => DATEADD('HOUR', -1, CURRENT_TIMESTAMP()),
DATE_RANGE_END => CURRENT_TIMESTAMP(),
RESULT_LIMIT => 100
))
ORDER BY START_TIME DESC;
-- Query history for a specific user
SELECT
QUERY_ID,
QUERY_TEXT,
TOTAL_ELAPSED_TIME,
BYTES_SCANNED,
ROWS_PRODUCED,
WAREHOUSE_NAME
FROM TABLE(INFORMATION_SCHEMA.QUERY_HISTORY_BY_USER(
USER_NAME => 'ANALYST_USER',
RESULT_LIMIT => 50
))
ORDER BY TOTAL_ELAPSED_TIME DESC;
-- Query history for a specific warehouse
SELECT *
FROM TABLE(INFORMATION_SCHEMA.QUERY_HISTORY_BY_WAREHOUSE(
WAREHOUSE_NAME => 'ANALYTICS_WH',
RESULT_LIMIT => 50
));Use the ACCOUNT_USAGE view for long-range analysis or an account-wide overview. Remember the up-to-45-minute delay and reach for INFORMATION_SCHEMA when you need real-time monitoring.
-- 30-day query summary
SELECT
USER_NAME,
WAREHOUSE_NAME,
COUNT(*) AS query_count,
AVG(TOTAL_ELAPSED_TIME) / 1000 AS avg_elapsed_sec,
SUM(BYTES_SCANNED) / POWER(1024, 3) AS total_scanned_tb,
AVG(PARTITIONS_SCANNED / NULLIF(PARTITIONS_TOTAL, 0)) AS avg_scan_ratio
FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY
WHERE START_TIME >= DATEADD('DAY', -30, CURRENT_TIMESTAMP())
AND EXECUTION_STATUS = 'SUCCESS'
GROUP BY USER_NAME, WAREHOUSE_NAME
ORDER BY total_scanned_tb DESC;Three angles to triage performance bottlenecks:
-- Top 20 longest-running queries in the last 7 days
SELECT
QUERY_ID,
SUBSTR(QUERY_TEXT, 1, 200) AS query_preview,
USER_NAME,
WAREHOUSE_NAME,
WAREHOUSE_SIZE,
TOTAL_ELAPSED_TIME / 1000 AS elapsed_sec,
COMPILATION_TIME / 1000 AS compile_sec,
EXECUTION_TIME / 1000 AS exec_sec,
QUEUED_OVERLOAD_TIME / 1000 AS queue_sec,
BYTES_SCANNED / POWER(1024, 3) AS scanned_tb
FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY
WHERE START_TIME >= DATEADD('DAY', -7, CURRENT_TIMESTAMP())
AND EXECUTION_STATUS = 'SUCCESS'
AND QUERY_TYPE = 'SELECT'
ORDER BY TOTAL_ELAPSED_TIME DESC
LIMIT 20;-- Queries with pruning under 50% (scanning more than 50% of partitions)
SELECT
QUERY_ID,
SUBSTR(QUERY_TEXT, 1, 200) AS query_preview,
PARTITIONS_SCANNED,
PARTITIONS_TOTAL,
ROUND(PARTITIONS_SCANNED / NULLIF(PARTITIONS_TOTAL, 0) * 100, 1) AS scan_pct,
BYTES_SCANNED / POWER(1024, 2) AS scanned_mb
FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY
WHERE START_TIME >= DATEADD('DAY', -7, CURRENT_TIMESTAMP())
AND PARTITIONS_TOTAL > 100
AND PARTITIONS_SCANNED / NULLIF(PARTITIONS_TOTAL, 0) > 0.5
AND EXECUTION_STATUS = 'SUCCESS'
ORDER BY scan_pct DESC
LIMIT 20;-- Queries with more than 5 seconds in the queue (a sign of warehouse shortage)
SELECT
QUERY_ID,
WAREHOUSE_NAME,
QUEUED_OVERLOAD_TIME / 1000 AS queue_sec,
QUEUED_PROVISIONING_TIME / 1000 AS provisioning_sec,
TOTAL_ELAPSED_TIME / 1000 AS elapsed_sec,
START_TIME
FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY
WHERE START_TIME >= DATEADD('DAY', -7, CURRENT_TIMESTAMP())
AND QUEUED_OVERLOAD_TIME > 5000
ORDER BY QUEUED_OVERLOAD_TIME DESC
LIMIT 20;| Column | Meaning | How to use it |
|---|---|---|
| TOTAL_ELAPSED_TIME | Total query execution time (ms) | Find queries with the largest cost impact |
| COMPILATION_TIME | Compilation time (ms) | Identify complex queries to optimize |
| QUEUED_OVERLOAD_TIME | Time waiting in the warehouse queue (ms) | Detect undersized warehouses |
| BYTES_SCANNED | Volume of data scanned | Detect full table scans |
| PARTITIONS_SCANNED / TOTAL | Scanned vs. total partitions | Evaluate pruning efficiency |
| BYTES_SPILLED_TO_LOCAL_STORAGE | Spill to local disk | Detect memory pressure |
| BYTES_SPILLED_TO_REMOTE_STORAGE | Spill to remote storage | Detect severe memory pressure |
SnowPro
問題 1
An account administrator wants to analyze query execution statistics for all users over the last 90 days. Which data source is most appropriate?
正解: B
INFORMATION_SCHEMA.QUERY_HISTORY() only covers the last 7 days and caps at 10,000 rows, so it doesn't fit a 90-day analysis. ACCOUNT_USAGE.QUERY_HISTORY retains 365 days of account-wide history, which matches the requirement. Just remember that the data lags by up to 45 minutes.
What is the difference between INFORMATION_SCHEMA.QUERY_HISTORY and ACCOUNT_USAGE.QUERY_HISTORY?
INFORMATION_SCHEMA.QUERY_HISTORY() is a table function that returns up to 10,000 rows of the last 7 days of query history with no delay. It only shows queries the current role has permission to see. ACCOUNT_USAGE.QUERY_HISTORY is a view that retains up to 365 days of account-wide history, but data is delayed by up to 45 minutes. Reading it requires IMPORTED PRIVILEGES on the SNOWFLAKE database.
Which columns identify the most expensive queries in QUERY_HISTORY?
There is no direct cost column, but you combine three metrics to find bottlenecks: TOTAL_ELAPSED_TIME (execution time in ms), BYTES_SCANNED (volume of data scanned), and PARTITIONS_SCANNED / PARTITIONS_TOTAL (pruning efficiency). Warehouse credits are billed by time, so queries with longer TOTAL_ELAPSED_TIME have the largest cost impact.
How do I retain QUERY_HISTORY data for longer than 365 days?
ACCOUNT_USAGE.QUERY_HISTORY only keeps 365 days of data. To retain it longer, create a task that periodically copies rows into a dedicated table with CREATE TABLE AS SELECT or INSERT INTO. A common pattern is a daily Serverless Task that incrementally copies the previous day's rows.
Practice with certification-focused question sets
無料で問題を解いてみるNicheeLab Editorial Team
NicheeLab editorial team focused on data engineering and cloud certification learning. Content is structured around practical study needs and official exam domains.
Snowflake Certifications: All 11 Exams Explained (2026)
Every SnowPro certification — Associate, Core, Specialty, Ad...
Snowflake Exam Difficulty Ranking: All 11 Certs Compared (2026)
All 11 SnowPro exams ranked by difficulty with study-time es...
Snowflake Study Guide: Fastest Pass Route by Exam (2026)
How to pass SnowPro certifications efficiently — official ma...
SnowPro Core (COF-C03): Complete Exam Guide (2026)
Pass the SnowPro Core exam — six domains, scope, sample ques...
SnowPro Associate Platform (SOL-C01): Complete Guide (2026)
The entry-level SnowPro Associate exam — scope, weighting, s...