Fabric 数据仓库中的数据群集

适用于:Microsoft Fabric 中的✅ 仓库

数据聚类分析是一种基于相似性来组织和存储数据的技术。 数据聚类分析通过将类似记录组合在一起,从而提高查询性能,并减少查询的计算和存储访问成本。

工作原理

数据聚类分析的工作原理是在引入期间将具有类似值的行存储在存储上的相邻位置。 数据聚类分析使用空间填充曲线来组织数据,从而在多个维度上保留局部性,这意味着在聚类分析列中具有类似值的行在物理上以物理方式存储在一起。 此方法通过执行文件跳过和减少扫描的文件数,极大地提高了查询性能。

与传统的词法排序不同,数据聚类分析使用复杂的算法引入,将具有类似列值的行保持在一起,即使表由多个列聚集也是如此。 这使得数据聚类分析非常适合范围查询、高基数筛选器和具有倾斜分布的大型表,从而加快读取速度、减少 I/O 以及更高效的资源使用。

下面是数据聚类分析的简化概念图:

展示数据仓库中数据聚类概念的图示。

在此图中,标有 Source data 标签的表格显示了不同颜色混合和突出显示的行,以表示目的地上的聚类分组。 已排序表拆分为三个文件段,每个文件段按类似颜色对行进行分组,演示如何根据列值将数据组织到优化的存储段。

引入期间,数据聚类分析元数据嵌入清单中,使仓库引擎能够就用户查询期间访问的文件做出智能决策。 此元数据与类似值的行一起存储的方式相结合,可确保具有筛选器谓词的查询可以跳过超出谓词范围的整个文件和行组。 例如:如果查询仅针对表数据的 10 个%,则聚类分析可确保仅扫描包含筛选器范围内数据的文件,从而减少 I/O 和计算消耗。 较大的表格从数据聚类中受益更多,因为文件跳过功能随着数据量的增加而扩展其优势。

何时使用数据聚类分析

在确定数据聚类分析是否有益时,调查仓库中的查询模式和表特征。 当查询重复筛选特定列以及基础表较大且包含中到高基数数据时,数据聚类分析最有效。 某些常见方案包括:

  • 包含筛选器的 WHERE 重复查询:如果工作负荷包含频繁的查询筛选特定列,则数据群集可确保在读取查询期间仅扫描相关文件。 这也适用于在仪表板、报表或计划作业中重复使用筛选器,并将筛选器作为 SQL 语句向下推送到仓库引擎时。
  • 较大的表:在扫描完整数据集代价较高时,数据聚类在大型表上最为有效。 通过组织具有数据聚类分析的行,仓库引擎可以跳过与查询筛选器不匹配的整个文件和行组,从而减少 I/O 和计算使用情况。
  • 中高基数列:具有较高基数的列(例如:具有许多非重复值的列(如 ID 或日期)受益于数据聚类分析,因为它们允许引擎隔离并并置类似的值。 这可实现高效的文件跳过,尤其是针对选择性查询。 具有低基数(例如:性别、区域)的列,其值会自然地分布在更多文件中,从而限制了跳过文件的机会。
  • 范围较窄的选择性查询:当查询通常面向少量数据且与 WHERE 筛选器结合使用时,数据聚类分析可确保仅读取包含相关行的文件。

数据聚类在数据引入过程中自动发生,无论行的引入方式如何。 引入数据后应用数据聚类分析时,无需用户进行任何操作。

CLUSTER BY 语法

使用 CLUSTER BY 子句在表创建期间定义数据聚类分析。 语法如下所示:

CREATE TABLE (Transact-SQL) 语法:

CREATE TABLE { warehouse_name.schema_name.table_name | schema_name.table_name | table_name } (
 [ ,... n ] –- Column list
) WITH (CLUSTER BY [ ,... n ]);

CREATE TABLE AS SELECT (Transact-SQL) 语法:

CREATE TABLE { warehouse_name.schema_name.table_name | schema_name.table_name | table_name } (
) WITH (CLUSTER BY[ ,... n ])
AS <select_statement>;

CLUSTER BY 子句要求至少为数据聚类分析指定一列,最多需要四列。

不支持创建使用数据聚类分析的 SELECT INTO 表。

数据类型支持

下面的表格汇总了可以在 CLUSTER BY 子句中使用的列类型:

类别 数据类型 支持数据聚类
精确数值 bit
精确数值 bigintintsmallintdecimal2numeric 是的
近似数值 floatreal 是的
日期和时间 datedatetime2time 是的
字符串1 char 是的
字符串1 varchar 是的
LOB 类型 varchar(max)varbinary(max)
二进制字符串 varbinary,uniqueidentifier

1 对于字符串类型(char/varchar),仅当生成列统计信息时,才使用前 32 个字符。 因此,包含长前缀的值的列在数据聚类分析方面可能具有有限的优势。

2 对于精度大于 18 的 十进制 类型,谓词在查询执行期间不会推送到存储。 如果将 十进制 类型用于数据聚类分析,则偏向精度较小的列。

具有不受支持的数据类型的列仍可以存在于使用数据聚类的表中,但不能与 CLUSTER BY 一起使用。

有关数据聚类分析的最佳做法

当根据实际查询模式选择聚类列时,尤其是选择中到高基数的列,并在查询中使用范围谓词,数据聚类效果更佳。

使用数据聚类分析时,请考虑以下最佳做法:

  • 数据聚类分析在大型表上更有效。
  • 尽可能进行批处理引入和更新,以一次性处理大量行,而不是使用较小的任务。 为了获得最佳性能,DML作应至少有 100 万行,以便受益于数据聚类分析。 连续插入、更新和删除后,数据压缩可以将较小的文件中的行合并为大小最佳的行。
  • 选择具有中到高基数的列进行数据聚类分析,因为它们因不同的值分布而产生更好的结果。 具有低基数的列可能会为文件修剪提供有限的机会。
  • 根据在仪表板、报表、计划作业或用户查询中频繁使用的谓词 WHERE 选择列。 相等联接条件不会受益于数据聚类。 有关如何使用 Query Insights 根据当前工作负载为数据聚类选择列的概述,请参阅 教程:在 Fabric 数据仓库中使用数据聚类
  • 不要对比严格必要的更多列进行数据聚类。 多列聚类分析增加了存储的复杂性,增加了开销,并且可能无法带来好处,除非所有列在具有谓词的查询中一起使用。
  • 所使用的 CLUSTER BY 列顺序并不重要,并且不会更改行的存储方式。
  • 使用 CREATE TABLE AS SELECT(CTAS) 创建包含数据聚类的表或使用 INSERT INTO ... SELECT 导入数据时,请尽可能简化这些语句的选择部分,以获得最佳数据聚类质量。

如果查询与查询谓词完全一致,则数据聚类分析可以显著降低成本。 与具有相同数据但未使用数据聚类功能的等效表相比,对于使用数据聚类的表,数据引入会占用更多的时间和容量单位(CU)。 发生这种情况是因为仓库引擎需要在摄取期间排序数据。 由于引入的数据是多次读取的,因此数据群集可以减少给定工作负荷的总体计算消耗。

系统视图

可以使用 sys.index_columns 查询数据聚类元数据。 该程序显示了用于数据聚类的所有列,包括在CLUSTER BY子句中使用的列序号。

以下查询列出了当前仓库的数据聚类分析中使用的所有列及其表:

SELECT
    t.name AS table_name,
    c.name AS column_name,
    ic.data_clustering_ordinal AS clustering_ordinal
FROM sys.tables t
JOIN sys.columns c
    ON t.object_id = c.object_id
JOIN sys.index_columns ic
    ON c.object_id = ic.object_id
   AND c.column_id = ic.column_id
WHERE ic.data_clustering_ordinal > 0
ORDER BY
    t.name,
    ic.data_clustering_ordinal;

注释

列序号仅作为参考信息显示,其顺序为定义表时在 CLUSTER BY 中所用的顺序。 如 最佳做法中所述,列顺序不会影响性能。

限制和备注

  • 当表包含具有高度可变数据大小的大型 varchar 列时,数据引入性能可能会降低。
    • 例如,假设有 varchar(200) 列的表:如果某些行只包含几个字符,而其他行则接近最大长度,则数据大小的巨大差异可能会对引入速度产生负面影响。
    • 此问题已知,将在即将发布的版本中得到解决。
  • IDENTITY 列不能用于 CLUSTER BY. 包含IDENTITY列的表仍可用于数据聚类,条件是它使用了包含CLUSTER BY在内的不同列。
  • 必须在创建表时定义数据聚类分析。 不支持将常规表转换为具有 CLUSTER BY 的表。 同样,不允许在创建表后修改聚类分析列。 如果需要不同的聚类分析列,可以选择使用 CREATE TABLE AS SELECT (CTAS) 创建具有所需聚类分析列的新表。
  • 在某些情况下,数据聚类分析可能会异步应用。 在这种情况下,使用后台任务重新组织数据,引入完成后,表可能无法完全优化。 这可能发生在以下情况下:
    • 当使用 INSERT INTO ... SELECTCREATE TABLE AS SELECT (CTAS) 时,如果源表和目标表的排序规则不同。
    • 从采用压缩 CSV 格式的外部数据引入时。
    • 引入语句的行数少于 100 万时。
  • 与不使用数据聚类分析的相同架构的表相比,对数据聚类分析表进行数据引入会产生开销。 这是因为需要额外的计算来优化存储。 当聚类列具有不区分大小写的排序规则时,还会产生更多额外开销。
  • 数据聚类分析可以受益于查询响应时间、容量单位(CU)消耗量或两者。

例子

答: 为销售数据创建一个集群表

此示例创建一个简单的 Sales 表,并使用 CustomerID 列和 SaleDate 列进行数据聚类。

CREATE TABLE Sales (
    SaleID INT,
    CustomerID INT,
    SaleDate DATE,
    Amount DECIMAL(10,2)
) WITH (CLUSTER BY (CustomerID, SaleDate))

B. 使用 CREATE TABLE AS SELECT 创建聚集表

此示例使用CREATE TABLE AS SELECT创建现有表Sales的副本,其中包含CLUSTER BYSaleDate列。

CREATE TABLE Sales_CTAS 
WITH (CLUSTER BY (SaleDate)) 
AS SELECT * FROM Sales

C. 查看用于给定表上的数据聚类分析的列

本示例列出用于表中数据聚类分析的 Sales 列。

SELECT
    c.name AS column_name,
    ic.data_clustering_ordinal AS clustering_ordinal
FROM sys.tables t
JOIN sys.columns c
    ON t.object_id = c.object_id
JOIN sys.index_columns ic
    ON c.object_id = ic.object_id
   AND c.column_id = ic.column_id
WHERE 
    ic.data_clustering_ordinal > 0
   AND t.name = 'Sales'
ORDER BY
    t.name,
    ic.data_clustering_ordinal;

结果:

显示聚类列及其序号位置的表。第一行列出了 CustomerID,具有聚类序号 1。第二行列出了 SaleDate,具有聚类序号 2。

D. 检查数据聚类分析的列选项的有效性

Query Insights 可以通过比较给定查询与其在原始表聚集副本上运行时的 CPU 时间和数据扫描量,帮助评估数据聚类对您的工作负载的影响。 以下示例演示如何检索分配的 CPU 时间和跨磁盘、内存和远程存储扫描的数据量,以获取特定查询。

SELECT 
    allocated_cpu_time_ms, 
    data_scanned_disk_mb, 
    data_scanned_memory_mb, 
    data_scanned_remote_storage_mb
FROM 
    queryinsights.exec_requests_history 
WHERE 
     distributed_statement_id = '<Query_Statement_ID>'

要评估的查询的分布式语句 ID 为 <Query_Statement_ID>

后续步骤