SNOWFLAKE.ACCOUNT_USAGE.ACCESS_HISTORY is a view that records, at the column level, which columns of which objects were accessed by every query run in your Snowflake account. It serves both as an audit trail for compliance requirements such as GDPR, CCPA, and SOX, and as a foundation for data lineage tracking. It is available on Enterprise Edition or higher.
The ACCESS_HISTORY view contains several semi-structured columns (ARRAY / OBJECT types), each recording access information at a different level.
| Column | Type | Description |
|---|---|---|
| query_id | VARCHAR | Unique identifier for the query |
| query_start_time | TIMESTAMP_LTZ | Time the query started executing |
| user_name | VARCHAR | User who executed the query |
| direct_objects_accessed | ARRAY | Objects directly referenced by the query (including views) and their column info |
| base_objects_accessed | ARRAY | Underlying base tables that were ultimately accessed, with column info |
| objects_modified | ARRAY | Objects modified by INSERT/UPDATE/DELETE and similar statements, with column info |
| object_modified_by_ddl | OBJECT | Object targeted by a DDL operation (CREATE/ALTER/DROP, etc.) |
| policies_referenced | ARRAY | Policies evaluated during access (masking, row access, etc.) |
-- 例: ビュー経由でテーブルにアクセスした場合
-- CREATE VIEW v_customers AS SELECT name, email FROM customers;
-- SELECT name FROM v_customers;
-- direct_objects_accessed の内容:
-- [{ "objectName": "V_CUSTOMERS",
-- "objectDomain": "View",
-- "columns": [{"columnName": "NAME"}] }]
-- base_objects_accessed の内容:
-- [{ "objectName": "CUSTOMERS",
-- "objectDomain": "Table",
-- "columns": [{"columnName": "NAME"}] }]
-- → ビュー V_CUSTOMERS を直接参照したが、
-- 実際にアクセスされたベーステーブルは CUSTOMERS の NAME 列-- 特定テーブルの列にアクセスしたユーザーと頻度を分析
SELECT
ah.user_name,
bo.value:objectName::STRING AS table_name,
col.value:columnName::STRING AS column_name,
COUNT(*) AS access_count,
MIN(ah.query_start_time) AS first_access,
MAX(ah.query_start_time) AS last_access
FROM SNOWFLAKE.ACCOUNT_USAGE.ACCESS_HISTORY ah,
LATERAL FLATTEN(input => ah.base_objects_accessed) bo,
LATERAL FLATTEN(input => bo.value:columns) col
WHERE ah.query_start_time >= DATEADD(DAY, -30, CURRENT_TIMESTAMP())
AND bo.value:objectName::STRING = 'CUSTOMERS'
GROUP BY 1, 2, 3
ORDER BY access_count DESC;-- テーブルへのWRITE操作を追跡
SELECT
ah.query_id,
ah.user_name,
ah.query_start_time,
om.value:objectName::STRING AS modified_table,
om.value:objectDomain::STRING AS object_type,
col.value:columnName::STRING AS modified_column
FROM SNOWFLAKE.ACCOUNT_USAGE.ACCESS_HISTORY ah,
LATERAL FLATTEN(input => ah.objects_modified) om,
LATERAL FLATTEN(input => om.value:columns) col
WHERE ah.query_start_time >= DATEADD(DAY, -7, CURRENT_TIMESTAMP())
AND om.value:objectName::STRING = 'CUSTOMER_PII'
ORDER BY ah.query_start_time DESC;When a masking policy or row access policy is evaluated during query execution, the policies_referenced column records the policy name and kind. This lets you see which policies are applied and how often.
-- マスキングポリシーの適用状況を分析
SELECT
pol.value:policyName::STRING AS policy_name,
pol.value:policyKind::STRING AS policy_kind,
COUNT(DISTINCT ah.query_id) AS query_count,
COUNT(DISTINCT ah.user_name) AS user_count
FROM SNOWFLAKE.ACCOUNT_USAGE.ACCESS_HISTORY ah,
LATERAL FLATTEN(input => ah.policies_referenced) pol
WHERE ah.query_start_time >= DATEADD(DAY, -30, CURRENT_TIMESTAMP())
GROUP BY 1, 2
ORDER BY query_count DESC;By combining base_objects_accessed and objects_modifiedin ACCESS_HISTORY, you can build a data lineage graph that shows which table's data flowed into which other tables.
-- データフロー(ソーステーブル → ターゲットテーブル)の可視化
SELECT
bo.value:objectName::STRING AS source_table,
om.value:objectName::STRING AS target_table,
ah.user_name,
COUNT(*) AS flow_count,
MAX(ah.query_start_time) AS latest_flow
FROM SNOWFLAKE.ACCOUNT_USAGE.ACCESS_HISTORY ah,
LATERAL FLATTEN(input => ah.base_objects_accessed) bo,
LATERAL FLATTEN(input => ah.objects_modified) om
WHERE ah.query_start_time >= DATEADD(DAY, -30, CURRENT_TIMESTAMP())
AND ARRAY_SIZE(ah.objects_modified) > 0
GROUP BY 1, 2, 3
ORDER BY flow_count DESC;-- PII列(email, ssn, phone等)へのアクセスを検出
SELECT
ah.user_name,
bo.value:objectName::STRING AS table_name,
col.value:columnName::STRING AS column_name,
COUNT(*) AS access_count
FROM SNOWFLAKE.ACCOUNT_USAGE.ACCESS_HISTORY ah,
LATERAL FLATTEN(input => ah.base_objects_accessed) bo,
LATERAL FLATTEN(input => bo.value:columns) col
WHERE ah.query_start_time >= DATEADD(DAY, -7, CURRENT_TIMESTAMP())
AND col.value:columnName::STRING IN ('EMAIL', 'SSN', 'PHONE_NUMBER', 'CREDIT_CARD')
GROUP BY 1, 2, 3
ORDER BY access_count DESC;| Use Case | Columns Used | Regulations / Requirements |
|---|---|---|
| PII column access auditing | base_objects_accessed → columns | GDPR / CCPA |
| Data lineage tracking | base_objects_accessed + objects_modified | SOX / internal controls |
| Masking policy application audit | policies_referenced | Security policy compliance |
| Detecting unused tables / columns | base_objects_accessed (identifying columns with no access) | Cost optimization |
| Audit trail for data changes | objects_modified → columns | HIPAA / financial regulations |
Security & Governance
問題 1
For a GDPR compliance audit, you need to identify every user who accessed the EMAIL column of the CUSTOMERS table in the last 30 days, either directly or through a view. Which approach is most appropriate?
正解: C
To identify users who accessed the EMAIL column of the actual base table — including access through views — you must use base_objects_accessed. direct_objects_accessed records the view name and is not suitable for column-level tracking on base tables. Option A's text search on query_text lacks accuracy because the column name can appear in other contexts. Option D's LOGIN_HISTORY only contains login information and no details about data access.
What is the difference between base_objects_accessed and direct_objects_accessed in ACCESS_HISTORY?
direct_objects_accessed records the objects directly referenced in the query's FROM clause (views, Dynamic Tables, etc.). base_objects_accessed records the underlying base tables that those objects internally accessed. For example, when you read data from table T through view V, V appears in direct_objects_accessed while T appears in base_objects_accessed. For data lineage tracking and security audits, base_objects_accessed lets you see the actual data access behind the views.
Does ACCESS_HISTORY require Enterprise Edition or higher?
Yes, the ACCESS_HISTORY view is available only on Enterprise Edition or higher. Standard Edition cannot access this view. Column-level data access tracking is an advanced governance feature, so organizations with compliance requirements such as GDPR or SOX must choose Enterprise Edition or higher. Note that accessing the ACCESS_HISTORY view also requires IMPORTED PRIVILEGES on the SNOWFLAKE database.
Can ACCESS_HISTORY also track WRITE operations (INSERT/UPDATE/DELETE)?
Yes, ACCESS_HISTORY tracks WRITE operations in addition to READ operations. The objects_modified column records information about objects changed by INSERT / UPDATE / DELETE / MERGE and similar statements. This lets you trace who wrote data to which column of which table and when, providing an audit trail for data changes. The columns array contains the list of accessed column names, so column-level WRITE auditing is also possible.
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...