4

如果我运行 CREATE EXTERNAL TABLE cetasTable AS SELECT 命令,则运行:

EXPLAIN
select * from cetasTable

我在分布式查询计划中看到:

<operation_cost cost="4231.099968" accumulative_cost="4231.099968" average_rowsize="2056" output_rows="428735" />

它似乎知道正确的行数,但是,如果我查看该表上没有创建统计信息,因为此查询返回零行:

select * from sys.stats where object_id = object_id('cetasTable')

如果我已经在 blob 存储中有文件并且我运行 CREATE EXTERNAL TABLE cetTable 命令,则运行:

EXPLAIN
select * from cetTable 

分布式查询计划显示 SQL DW 认为外部表中只有 1000 行:

  <operation_cost cost="4.512" accumulative_cost="4.512" average_rowsize="940" output_rows="1000" />

当然,我可以创建统计信息以确保 SQL DW 在创建分布式查询计划时知道正确的行数。但是有人能解释一下它是如何在某些时候知道正确的行数以及正确的行数存储在哪里的吗?

4

1 回答 1

4

您看到的是使用 CxTAS(CTAS、CETAS 或 CRTAS)创建的表与 CREATE TABLE 之间的区别。

当您运行 CREATE TABLE 时,行计数和页计数值是固定的,因为表是空的。如果内存服务固定值是 1000 行和 100 页。当您使用 CTAS 创建表时,它们不是固定的。CTAS 命令知道实际值,因为它刚刚在单个命令中创建并填充了表。因此,当使用 CxTAS 时,元数据正确地反映了表 SIZE。这很好。当通过 CxTAS 创建表而不是通过 CREATE 表创建表时,基于 APS / SQLDW 成本的优化器可以立即根据表 SIZE 更好地估计 MPP 计划生成。

准确了解表大小很重要。

想象一下,您有一个使用 CREATE TABLE 创建的表,然后使用 INSERT 将 10 亿行插入到该表中。shell 数据库仍然认为该表有 1000 行和 100 页。然而,情况显然并非如此。这样做的原因是因为此时表大小属性不会自动更新。

现在想象一个查询被触发,需要在这个表上移动数据。事情可能会开始出错。您现在更有可能看到引擎做出糟糕的 MPP 计划选择(通常使用 BROADCAST 而不是 SHUFFLE),因为它不了解表大小等。

你能做些什么来改善这一点?

每个表至少创建一个列级统计对象。一般来说,您将在查询中的 JOINS、GROUP BY、WHERE 和 ORDER BY 中使用的所有列上创建统计对象。稍后我将解释统计信息生成的基本过程。我只想强调,这里的号召性用语是确保您创建和维护您的统计对象。

当为列执行 CREATE STATISTICS 时,实际上会发生三个事件。

1) 表级信息在 CONTROL 节点上更新

2) 在计算节点上的每个分布上创建列级统计对象

3) 在 CONTROL 节点上创建和更新列级统计对象

1) 表级信息在 CONTROL 节点上更新

第一步是更新表级信息。为此,APS / SQLDW 对每个物理分布执行 DBCC SHOW_STATISTICS (table_name) WITH STAT_STREAM;合并结果并将它们存储在 shell 数据库的目录元数据中。行数保存在 sys.partitions 上,页数保存在 sys.allocation_units 上。Sys.partitions 在 SQLDW 和 APS 中对您都是可见的。但是,此时最终用户看不到 sys.allocation_units。我为那些熟悉 SQL Server 内部的人参考了该位置以获取信息和上下文。

在此阶段结束时,控制节点上的 shell 数据库中保存的元数据已针对行数和页数进行了更新。现在由 CREATE TABLE 创建的表和 CTAS 之间没有区别 - 两者都知道大小。

2) 在计算节点上的每个分布上创建列级统计对象

必须在每个 COMPUTE 节点上的每个分布中创建统计对象。通过创建重要的统计对象,已创建列的详细统计数据(特别是直方图和密度向量)。

APS 和 SQLDW 使用此信息来生成分布级别的 SMP 计划。APS / SQLDW 仅在物理层中使用 SMP 计划。因此,此时统计数据不在可用于生成 MPP 计划的位置。信息是分发的,并且无法及时访问以进行基于成本的优化。因此需要第三步...

3) 在 CONTROL 节点上创建和更新列级统计对象

一旦数据在 COMPUTE 层的分布上以物理方式创建,它必须被汇集在一起​​并以逻辑方式保存,以促进基于 MPP 计划成本的优化。CONTROL 节点上的 shell 数据库也创建了一个统计对象。这是统计对象的逻辑表示。

但是,shell 数据库 stat 尚未反映在 COMPUTE 节点上的分布中物理保存的列级统计信息。因此,在 CONTROL 节点上的 shell 数据库中的统计信息对象需要在创建后立即更新。

DBCC SHOW_STATISTICS (table_name, stat_name) WITH STAT_STREAM 用于执行此操作。

请注意,该命令有第二个参数。这会改变结果集;为 APS / SQLDW 提供为该列构建统计对象的逻辑视图所需的所有信息。

我希望这有助于解释您所看到的内容,以及如何创建统计信息以及为什么它们对 Azure SQL DW 和 APS 很重要。

于 2015-12-31T16:58:58.443 回答