成本归因¶
组织可以将使用 Snowflake 的成本归因于组织内的逻辑单元(例如部门、环境和项目),以深入了解这些成本。这种 chargeback(按存储容量使用计费)或 showback(按存储容量使用显示)模式对于会计目的很有用,但它也允许组织确定哪些单位的支出最多。此洞察力有助于确定组织内可以从控制和优化中受益的领域,以降低成本。
各项资源的成本归因¶
备注
Object Tagging 在 Enterprise Edition 或更高版本中可用。
要将成本归因到不同分组(如部门、环境或项目),最直接有效的方法是使用 对象标记 功能标记特定资源。在此策略中,管理员创建一个标签(例如 cost_center
),然后定义该标签的可能值列表(例如 sales
、finance
)。在本例中,每个成本中心都有一个唯一的标签值。然后将标签/值组合分配给成本中心使用的资源。当这些资源使用 Credit 时,您可以运行按标签值分组的报告。由于此标签值直接对应于组织内的特定分组,因此可以准确地将成本归因。
利用对象标记,可以基于账户等普通对象或基于表等特定对象将成本归因。请注意,并非所有 可标记对象 都会累积成本。从成本管理的角度来看,只有存在架构视图,且该视图包含与对象相关的使用情况或成本数据时,标记对象才有意义。有关 Snowflake 使用情况和成本视图的列表,请参阅 浏览总体成本。
归因工作流程¶
使用对象标签将成本归因包括三项基本任务:
设计标签策略并创建适当的标签。
使用正确的标签/值对标记资源。
根据使用情况和标签数据运行报告。
为了帮助说明此工作流程,考虑这样一个 Snowflake 账户:
有两个成本中心:销售和财务。
有三个仓库。销售部门使用仓库 1 和仓库 2,而财务部门使用仓库 3。

在本例中,目标是将与每个仓库关联的仓库成本归因到相应的部门。
备注
下面的示例假定已向 tag_admin
角色授予了适当的权限。组织可以使用粒度 标记权限 来开发安全标记策略。
- 任务 1:设计标记策略并创建适当的标签
对于本例,具有适当权限的管理员创建一个名为
cost_center
的标签。USE ROLE tag_admin; USE SCHEMA my_db.my_schema; CREATE TAG cost_center;
- 任务 2:使用正确的标签/值对标记对象
标签管理员将适当的标签/值对应用于仓库。例如,由于销售部门使用
warehouse1
和warehouse2
,因此将对这两个资源应用相同的标签/值组合。USE ROLE tag_admin; ALTER WAREHOUSE warehouse1 SET TAG cost_center='SALES'; ALTER WAREHOUSE warehouse2 SET TAG cost_center='SALES'; ALTER WAREHOUSE warehouse3 SET TAG cost_center='FINANCE';
备注
如果管理员希望控制可以在对象上设置的值,则可以在创建标签时使用可选的
allowed_values
参数。有关详细信息,请参阅 CREATE TAG。- 任务 3:根据使用情况和标签数据运行报告
可以根据具有
cost_center
标签的资源的使用情况生成报告,以将成本归因。该数据可以在 Snowsight 中获得,也可以通过查询SNOWFLAKE.ACCOUNT_USAGE
架构获得。- Snowsight:
切换到具有 :ref:` ACCOUNT_USAGE 架构访问权限 <label-enabling_usage_for_other_roles>` 的角色。
导航到 Admin » Cost Management。
选择 Consumption。
从 Tags 下拉列表中选择
cost_center
标签。要关注特定成本中心,请从标签的值列表中选择一个值。
选择 Apply。
有关在 Snowsight 中进行筛选的更多详细信息,请参阅 按标签筛选。
- SQL:
Account Usage 架构包含有关资源使用情况和架构中的标签的数据。
您可以查看给定月份内所有仓库的成本归属及其标签和标签值。此查询还标识无标记仓库:
SELECT tag_references.tag_name, COALESCE(tag_references.tag_value, 'untagged') AS tag_value, SUM(warehouse_metering_history.credits_used_compute) AS total_credits FROM snowflake.account_usage.warehouse_metering_history LEFT JOIN snowflake.account_usage.tag_references ON warehouse_metering_history.warehouse_id = tag_references.object_id WHERE warehouse_metering_history.start_time >= DATE_TRUNC('MONTH', DATEADD(MONTH, -1, CURRENT_DATE)) AND warehouse_metering_history.start_time < DATE_TRUNC('MONTH', CURRENT_DATE) GROUP BY tag_references.tag_name, COALESCE(tag_references.tag_value, 'untagged') ORDER BY total_credits DESC;
+-------------+-------------+-----------------+ | TAG_NAME | TAG_VALUE | TOTAL_CREDITS | |-------------+-------------+-----------------| | NULL | untagged | 20.360277159 | | COST_CENTER | Sales | 17.173333333 | | COST_CENTER | Finance | 8.14444444 | +-------------+-------------+-----------------+
有关使用对象标签的完整详细信息,请参阅 Object Tagging。
归因查询的成本¶
您可以使用 QUERY_ATTRIBUTION_HISTORY 视图 根据查询来归因成本。每查询成本是执行查询的仓库 Credit 使用量。此成本不包括因查询执行而产生的任何其他 Credit 使用量。例如,下列内容不包括在查询成本中:
数据传输成本
存储成本
云服务成本
无服务器功能的成本
AI 服务处理的词元的成本
对于并发执行的查询,仓库的成本归因于基于给定时间间隔内资源使用量的加权平均值的单个查询。
每查询成本不包括仓库 空闲时间。空闲时间是在仓库中没有运行查询的时间段,可以在仓库级别进行测量。
按标记、用户和查询的成本归因¶
您可以按标记、用户或查询(例如,经常性查询)进行仓库和查询成本归因。
基于查询标签的仓库成本归因¶
您可以使用 QUERY_TAG 参数在不同工作负载之间分配成本。可以在会话级别为工作负载或一组查询分配查询标记。有关基于标记的归因的详细信息,请参阅 归因工作流。
要为会话设置查询标记,请执行以下步骤:
创建标记。例如,为财务团队创建一个标记:
CREATE TAG finance;
为当前会话设置查询标记:
ALTER SESSION SET query_tag = finance;
finance
标记与会话期间执行的所有查询相关联。要查看本月所有已标记查询的仓库成本,请执行以下语句。请注意,此查询将整个仓库计算成本分配给标记(包括空闲时间)以进行调节:
WITH wh_bill AS ( SELECT SUM(credits_used_compute) AS compute_credits FROM SNOWFLAKE.ACCOUNT_USAGE.WAREHOUSE_METERING_HISTORY WHERE start_time >= DATE_TRUNC('MONTH', CURRENT_DATE) AND start_time < CURRENT_DATE ), tag_credits AS ( SELECT COALESCE(NULLIF(query_tag, ''), 'untagged') AS tag, SUM(credits_attributed_compute) AS credits FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_ATTRIBUTION_HISTORY WHERE start_time >= DATE_TRUNC('MONTH', CURRENT_DATE) AND start_time < CURRENT_DATE GROUP BY tag ), total_credit AS ( SELECT SUM(credits) AS sum_all_credits FROM tag_credits ) SELECT tc.tag, tc.credits / t.sum_all_credits * w.compute_credits AS attributed_credits FROM tag_credits tc, total_credit t, wh_bill w;
基于用户的仓库成本归因¶
您可以按用户来分配仓库成本。例如,要确定当月归因于每个用户的仓库总成本,请执行以下语句:
WITH wh_bill AS (
SELECT SUM(credits_used_compute) AS compute_credits
FROM SNOWFLAKE.ACCOUNT_USAGE.WAREHOUSE_METERING_HISTORY
WHERE start_time >= DATE_TRUNC('MONTH', CURRENT_DATE)
AND start_time < CURRENT_DATE
),
user_credits AS (
SELECT user_name, SUM(credits_attributed_compute) AS credits
FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_ATTRIBUTION_HISTORY
WHERE start_time >= DATE_TRUNC('MONTH', CURRENT_DATE)
AND start_time < CURRENT_DATE
GROUP BY user_name
),
total_credit AS (
SELECT SUM(credits) AS sum_all_credits
FROM user_credits
)
SELECT u.user_name,
u.credits / t.sum_all_credits * w.compute_credits AS attributed_credits
FROM user_credits u, total_credit t, wh_bill w
ORDER BY attributed_credits DESC;
+-----------+--------------------+
| USER_NAME | ATTRIBUTED_CREDITS |
|-----------+--------------------|
| JSMITH | 17.173333333 |
|-----------+--------------------|
| MJONES | 8.14444444 |
|-----------+--------------------|
| SYSTEM | 5.33985393 |
+-----------+--------------------+
经常性查询的查询成本¶
对于经常性或类似查询,请使用 query_hash
或:code:query_parameterized_hash
按查询对成本进行分组。
要查找当月最昂贵的经常性查询,请执行以下语句:
SELECT query_parameterized_hash,
COUNT(*) AS query_count,
SUM(credits_attributed_compute) AS total_credits
FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_ATTRIBUTION_HISTORY
WHERE start_time >= DATE_TRUNC('MONTH', CURRENT_DATE)
AND start_time < CURRENT_DATE
GROUP BY query_parameterized_hash
ORDER BY total_credits DESC
LIMIT 20;
有关基于查询 ID 的其他查询,请参阅 示例。
分层查询的查询成本¶
对于发出多个层次查询的存储过程,您可以使用程序的根查询 ID 计算程序的归因查询成本。
要查找存储过程的根查询 ID,请使用 ACCESS_HISTORY 视图。例如,要查找存储过程的根查询 ID,请设置
query_id
并执行以下语句:SET query_id = '<query_id>'; SELECT query_id, parent_query_id, root_query_id, direct_objects_accessed FROM SNOWFLAKE.ACCOUNT_USAGE.ACCESS_HISTORY WHERE query_id = $query_id;
有关更多信息,请参阅 示例:使用存储过程的祖先查询。
要计算整个程序的查询成本之和,请替换
<root_query_id>
并执行以下语句:SET query_id = '<root_query_id>'; SELECT SUM(credits_attributed_compute) AS total_attributed_credits FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_ATTRIBUTION_HISTORY WHERE (root_query_id = $query_id OR query_id = $query_id);