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')

ブロブ ストレージに既にファイルがあり、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 コマンドが 1 つのコマンドでテーブルを作成して入力したばかりであるため、既知です。したがって、CxTAS を使用すると、メタデータはテーブル SIZE を正しく反映します。これはいい。APS / SQLDW コストベースのオプティマイザーは、CREATE テーブルではなく CxTAS を介してテーブルが作成された場合、テーブル SIZE に基づいて MPP プラン生成のより良い見積もりを即座に行うことができます。

テーブルのサイズを正確に理解することが重要です。

CREATE TABLE を使用して作成されたテーブルがあり、INSERT を使用してそのテーブルに 10 億行が挿入されたとします。シェル データベースは、テーブルに 1000 行と 100 ページがあるとまだ認識しています。しかし、これは明らかにそうではありません。これは、現時点ではテーブル サイズ属性が自動的に更新されないためです。

ここで、このテーブルでのデータ移動を必要とするクエリが起動されたとします。物事がうまくいかなくなるかもしれません。エンジンは特にテーブル サイズを理解していないため、不適切な MPP プランの選択 (通常は SHUFFLE ではなく BROADCAST を使用) を行う可能性が高くなります。

これを改善するために何ができますか?

テーブルごとに少なくとも 1 つの列レベルの統計オブジェクトを作成します。一般的に言えば、クエリの JOINS、GROUP BY、WHERE、および ORDER BY で使用されるすべての列に統計オブジェクトを作成します。統計生成の基本的なプロセスについては、すぐに説明します。ここで強調したいのは、統計オブジェクトを確実に作成して維持することです。

列に対して CREATE STATISTICS が実行されると、実際には 3 つのイベントが発生します。

1) CONTROL ノードでテーブル レベルの情報が更新される

2) 列レベルの統計オブジェクトは、COMPUTE ノードのすべてのディストリビューションで作成されます

3) 列レベルの統計オブジェクトが作成され、CONTROL ノードで更新されます。

1) CONTROL ノードでテーブル レベルの情報が更新される

最初のステップは、テーブル レベルの情報を更新することです。これを行うために、APS/SQLDW はすべての物理ディストリビューションに対して DBCC SHOW_STATISTICS (table_name) WITH STAT_STREAM を実行します。結果をマージし、シェル データベースのカタログ メタデータに保存します。行数は sys.partitions で保持され、ページ数は sys.allocation_units で保持されます。Sys.partitions は、SQLDW と APS の両方で表示されます。ただし、現時点では sys.allocation_units はエンド ユーザーには表示されません。ここでは、SQL Server の内部構造に精通しているユーザー向けに情報とコンテキストを参照しました。

この段階の最後に、CONTROL ノードのシェル データベースに保持されているメタデータは、行数とページ数の両方について更新されています。CREATE TABLE によって作成されたテーブルと CTAS によって作成されたテーブルの間に違いはなくなりました。どちらもサイズを認識しています。

2) 列レベルの統計オブジェクトは、COMPUTE ノードのすべてのディストリビューションで作成されます

統計オブジェクトは、すべての COMPUTE ノードのすべてのディストリビューションで作成する必要があります。重要な統計オブジェクトを作成することにより、列の詳細な統計データ (特にヒストグラムと密度ベクトル) が作成されました。

この情報は、配布レベルの SMP 計画を生成するために APS および SQLDW によって使用されます。SMP プランは、PHYSICAL レイヤーでのみ APS / SQLDW によって使用されます。したがって、この時点では、統計データは MPP 計画の生成に使用できる場所にはありません。情報は分散されており、コストベースの最適化のためにタイムリーにアクセスすることはできません。したがって、3番目のステップが必要です...

3) 列レベルの統計オブジェクトが作成され、CONTROL ノードで更新されます。

データが COMPUTE レイヤーのディストリビューションで物理的に作成されたら、それらをまとめて論理的に保持し、MPP プランのコスト ベースの最適化を促進する必要があります。CONTROL ノードのシェル データベースも、統計オブジェクトを作成します。これは、統計オブジェクトの論理表現です。

ただし、シェル データベースの stat は、COMPUTE ノードのディストリビューションで物理的に保持されている列レベルの統計情報をまだ反映していません。したがって、CONTROL ノード上のシェル データベース内の統計オブジェクトは、作成後すぐに更新する必要があります。

DBCC SHOW_STATISTICS (table_name, stat_name) WITH STAT_STREAM を使用してこれを行います。

コマンドには 2 番目のパラメーターがあることに注意してください。これにより、結果セットが変更されます。その列の統計オブジェクトの論理ビューを構築するために必要なすべての情報を APS / SQLDW に提供します。

これが、あなたが見たものだけでなく、統計がどのように作成されるか、そして Azure SQL DW と APS にとってなぜ統計が重要なのかを説明するのに役立つことを願っています。

于 2015-12-31T16:58:58.443 に答える