一般的な部分式の削除の説明
APS CU7.3 では、SQL クエリ オプティマイザーでの一般的な部分式の削除により、クエリのパフォーマンスが向上します。 この向上により、2 つの方法でクエリが向上されます。 1 つ目の利点は、このような式を特定して排除することで、SQL のコンパイル時間を短縮できることです。 2 つ目の重要な利点は、これらの冗長部分式のデータ移動操作が排除されるため、クエリの実行時間が短縮されることです。
select top 100 asceding.rnk, i1.i_product_name best_performing, i2.i_product_name worst_performing
from(select *
from (select item_sk,rank() over (order by rank_col asc) rnk
from (select ss_item_sk item_sk,avg(ss_net_profit) rank_col
from store_sales ss1
where ss_store_sk = 8
group by ss_item_sk
having avg(ss_net_profit) > 0.9*(select avg(ss_net_profit) rank_col
from store_sales
where ss_store_sk = 8
and ss_hdemo_sk is null
group by ss_store_sk))V1)V11
where rnk < 11) asceding,
(select *
from (select item_sk,rank() over (order by rank_col desc) rnk
from (select ss_item_sk item_sk,avg(ss_net_profit) rank_col
from store_sales ss1
where ss_store_sk = 8
group by ss_item_sk
having avg(ss_net_profit) > 0.9*(select avg(ss_net_profit) rank_col
from store_sales
where ss_store_sk = 8
and ss_hdemo_sk is null
group by ss_store_sk))V2)V21
where rnk < 11) descending,
item i1,
item i2
where asceding.rnk = descending.rnk
and i1.i_item_sk=asceding.item_sk
and i2.i_item_sk=descending.item_sk
order by asceding.rnk
;
TPC-DS ベンチマーク ツールからの上記のクエリについて考慮します。 上記のクエリでは、サブクエリは同じですが、rank() over 関数を持つ order by 句は 2 つの異なる方法で並べ替えられます。 CU7.3 より前では、このサブクエリは 2 回評価され、1 回は昇順、1 回は降順で実行され、2 つのデータ移動操作が発生します。 APS CU7.3 をインストールすると、サブクエリ パーツが 1 回評価されるため、データ移動が減り、クエリの処理が速くなります。
APS CU7.3 にアップグレードした後でも機能をテストできる、"OptimizeCommonSubExpressions" という機能スイッチが導入されました。 この機能は規定ではオンになっていますが、オフにすることもできます。
注意
機能スイッチの値を変更するには、サービスを再起動が必要です。
テスト環境で次のテーブルを作成し、上記のクエリの explain プランを評価することで、サンプル クエリを試すことができます。
CREATE TABLE [dbo].[store_sales] (
[ss_sold_date_sk] int NULL,
[ss_sold_time_sk] int NULL,
[ss_item_sk] int NOT NULL,
[ss_customer_sk] int NULL,
[ss_cdemo_sk] int NULL,
[ss_hdemo_sk] int NULL,
[ss_addr_sk] int NULL,
[ss_store_sk] int NULL,
[ss_promo_sk] int NULL,
[ss_ticket_number] int NOT NULL,
[ss_quantity] int NULL,
[ss_wholesale_cost] decimal(7, 2) NULL,
[ss_list_price] decimal(7, 2) NULL,
[ss_sales_price] decimal(7, 2) NULL,
[ss_ext_discount_amt] decimal(7, 2) NULL,
[ss_ext_sales_price] decimal(7, 2) NULL,
[ss_ext_wholesale_cost] decimal(7, 2) NULL,
[ss_ext_list_price] decimal(7, 2) NULL,
[ss_ext_tax] decimal(7, 2) NULL,
[ss_coupon_amt] decimal(7, 2) NULL,
[ss_net_paid] decimal(7, 2) NULL,
[ss_net_paid_inc_tax] decimal(7, 2) NULL,
[ss_net_profit] decimal(7, 2) NULL
)
WITH (CLUSTERED COLUMNSTORE INDEX, DISTRIBUTION = HASH([ss_item_sk]), PARTITION ([ss_sold_date_sk] RANGE RIGHT FOR VALUES (2450815, 2451180, 2451545, 2451911, 2452276, 2452641, 2453006)));
CREATE TABLE [dbo].[item] (
[i_item_sk] int NOT NULL,
[i_item_id] char(16) COLLATE Latin1_General_100_CI_AS_KS_WS NOT NULL,
[i_rec_start_date] date NULL,
[i_rec_end_date] date NULL,
[i_item_desc] varchar(200) COLLATE Latin1_General_100_CI_AS_KS_WS NULL,
[i_current_price] decimal(7, 2) NULL,
[i_wholesale_cost] decimal(7, 2) NULL,
[i_brand_id] int NULL,
[i_brand] char(50) COLLATE Latin1_General_100_CI_AS_KS_WS NULL,
[i_class_id] int NULL,
[i_class] char(50) COLLATE Latin1_General_100_CI_AS_KS_WS NULL,
[i_category_id] int NULL,
[i_category] char(50) COLLATE Latin1_General_100_CI_AS_KS_WS NULL,
[i_manufact_id] int NULL,
[i_manufact] char(50) COLLATE Latin1_General_100_CI_AS_KS_WS NULL,
[i_size] char(20) COLLATE Latin1_General_100_CI_AS_KS_WS NULL,
[i_formulation] char(20) COLLATE Latin1_General_100_CI_AS_KS_WS NULL,
[i_color] char(20) COLLATE Latin1_General_100_CI_AS_KS_WS NULL,
[i_units] char(10) COLLATE Latin1_General_100_CI_AS_KS_WS NULL,
[i_container] char(10) COLLATE Latin1_General_100_CI_AS_KS_WS NULL,
[i_manager_id] int NULL,
[i_product_name] char(50) COLLATE Latin1_General_100_CI_AS_KS_WS NULL
)
WITH (CLUSTERED INDEX ( [i_item_sk] ASC ), DISTRIBUTION = REPLICATE);
クエリの説明プランを見ると、CU7.3 より前 (または機能スイッチがオフの場合) に、クエリに 17 個の操作の合計数があり、CU7.3 以降 (または機能スイッチがオン) の場合、同じクエリに 9 つの操作の合計数が表示されます。 データ移動操作をカウントするだけで、以前のプランには、新しいプランの 4 つの移動操作と 2 つの移動操作があることがわかります。 新しいクエリ オプティマイザーでは、新しいプランで既に作成した一時テーブルを再利用することで、2 つのデータ移動操作を減らすことが可能になり、クエリの実行時間が短縮されました。