Dada uma tabela simples baseada em linhas sem um PK, mas com um índice clusterizado baseado em linhas da seguinte forma:
create clustered index [CX_PropertyValue] ON [dbo].[PropertyValue] ([PropertyId], [Value])
Em seguida, desejo adicionar um índice de armazenamento de colunas segmentado na mesma ordem que o índice clusterizado acima:
create nonclustered columnstore index CS_IX_PropertyValue on dbo.PropertyValue(
PropertyId, Value
)
with (drop_existing = on, maxdop = 1); -- maxdop=1 to preserve the order by property
A dica do MaxDop para preservar a ordem veio de: aqui
Em seguida, a consulta a seguir foi usada para relatar o min/max data_id para a coluna PropertyId e o intervalo completo foi relatado em cada um dos 7 segmentos:
create view [Common].[ColumnStoreSegmentationView]
as
/*---------------------------------------------------------------------------------------------------------------------
Purpose: List ColumnStore table segment min/max of columns.
Source: https://joyfulcraftsmen.com/blog/cci-how-to-load-data-for-better-columnstore-segment-elimination/
https://dba.stackexchange.com/a/268329/9415
Modified By Description
---------- ---------- -----------------------------------------------------------------------------------------
2020.06.02 crokusek/inet Initial Version
---------------------------------------------------------------------------------------------------------------------*/
select --top 20000000000
s.Name as SchemaName,
t.Name as TableName,
i.Name as IndexName,
c.name as ColumnName,
c.column_id as ColumnId,
cs.segment_id as SegmentId,
cs.min_data_id as MinValue,
cs.max_data_id as MaxValue
from sys.schemas s
join sys.tables t
on t.schema_id = s.schema_id
join sys.partitions as p
on p.object_id = t.object_id
join sys.indexes as I
on i.object_id = p.object_id
and i.index_id = p.index_id
join sys.index_columns as ic
on ic.[object_id] = I.[object_id]
and ic.index_id = I.index_id
join sys.columns c
on c.object_id = t.object_id
and c.column_id = ic.column_id
join sys.column_store_segments cs
on cs.hobt_id = p.hobt_id
and cs.column_id = ic.index_column_id
--order by s.Name, t.Name, i.Name, c.Name, cs.Segment_Id
GO
Tentei tornar o índice clusterizado único, o que afetou ligeiramente os intervalos relatados, mas ainda não estava aumentando monotonicamente.
Alguma ideia?
Aqui está um link que realizou a segmentação dessa maneira, mas não vejo diferença.
Versão: Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64)
Isso não tem suporte direto para índices columnstore não clusterizados .
Funciona para columnstore clusterizado .
O Azure Synapse Analytics tem suporte ao idioma para fazer isso em uma etapa, por exemplo:
Essa sintaxe ainda não chegou ao produto de caixa do SQL Server, embora esteja disponível em um sinalizador de recurso não documentado, portanto, talvez não esteja longe. No entanto, ainda não funcionará em um índice columnstore não clusterizado.
Solução Geral
O melhor que você pode fazer é criar o índice rowstore não
MAXDOP = 1
clusterizado com , e substituí-lo por um índice columnstore não clusterizado comMAXDOP = 1
eDROP_EXISTING = ON
.Isso não garante a preservação da ordem desejada, mas é altamente provável:
Isso lhe dará a melhor chance de conseguir a eliminação de rowgroup ao filtrar em
PropertyId
.Caso especial
Quando a ordenação desejada corresponde ao índice clusterizado rowstore (como parece ser o caso na pergunta), não há necessidade de criar primeiro um índice não clusterizado rowstore. A documentação diz :
Então, no seu caso, deve ser suficiente executar apenas:
Veja esta demonstração do db<>fiddle .
Metadados
Você pode ver os valores mínimo e máximo para cada grupo de linhas e coluna usando: