AFAIK列ストアインデックスはセグメント(100万行)の最小値/最大値を格納するため、この情報を使用して不要なデータを削除できます。この機能は、等価述語では機能するようですが、結合やサブクエリフィルターなどのより複雑なケースでは機能しません。 SQL Server 2014では、結合またはサブクエリで列ストアメタデータフィルタリングを使用できますか?
以下は私のテストケースです:
--create table generate_series with 67_108_864 rows (runs about 5 mins)
set nocount on;
create table generate_series(c bigint);
insert into generate_series select 1;
declare @i int = 26;
while @i != 0
begin
insert into generate_series WITH (TABLOCK)
select
(select count(*) from generate_series)
+ row_number() over (order by (select null)) as c
from generate_series;
set @i = @i - 1;
end;
create nonclustered columnstore index cstore on generate_series(c);
--Test queries
-- 0 seconds (very fast)
select * from generate_series where c = 100;
-- 8 seconds (slow)
select 100 as c into #tmp;
select * from generate_series where c in (select c from #tmp);
あなたが説明しているパフォーマンスの最適化は 行グループの除去 として知られています。 SQL Server2016とSQLServer 2014の両方で両方のクエリを使用して行グループを削除できますが、SQL Server2014には追加の制限があります。
まず、SQL Server2016でテストしてみましょう。次のクエリは非常にすばやく終了します。
select *
from generate_series
where c = 100
OPTION (MAXDOP 1);
SQL Server 2016は、SET STATISTICS IO ON;
を介して行グループの削除に関する追加の診断情報を提供するので、それを利用しましょう。
テーブル 'generate_series'。セグメント読み取り1、セグメントスキップ68。
SQL Serverの実行時間:CPU時間= 0ミリ秒、経過時間= 9ミリ秒。
このクエリも高速です。
select *
from generate_series
where c in (select c from #tmp)
OPTION (MAXDOP 8);
統計出力:
テーブル 'generate_series'。セグメント読み取り1、セグメントスキップ68。
SQL Serverの実行時間:CPU時間= 0ミリ秒、経過時間= 11ミリ秒。
このクエリも高速です。
select *
from generate_series
where c in (select c from #tmp)
OPTION (MAXDOP 1);
テーブル 'generate_series'。セグメント読み取り1、セグメントスキップ68。
SQL Serverの実行時間:CPU時間= 0ミリ秒、経過時間= 5ミリ秒。
クエリごとに、SQLServerは68行グループをスキップできます。 IDが100の行グループからのみデータを読み取ります。最終クエリの計画では、最適化されたビットマップが適用されていることがわかります。
そのビットマップにより、結合による行グループの削除が可能になります。
SQL Server 2014では、結合があり、MAXDOP
が1である最後のクエリを除いて、クエリに対して同様のパフォーマンス結果が得られます。これは、実行に21秒かかります。クエリプランは次のとおりです。
ビットマップがなく、スキャンがバッチモードで実行されていません。 6700万行すべてをハッシュ結合に送り返します。
SQL Server 2014では、シリアルプランはバッチモードの対象ではありません。クエリが何らかの理由でシリアルで実行されている場合は、発生したパフォーマンスの低下を説明できます。 c = 100
を直接フィルタリングするクエリも行モードで実行されますが、それでもすぐに終了することに注意してください。