Eu tenho uma grande tabela de relatórios (aproximadamente 6 bilhões de linhas) ocupando aproximadamente 400 GB de armazenamento em um banco de dados sql do azure. Eu tenho tentado convertê-lo em uma tabela columnstore usando os seguintes comandos:
insert Logs(Message) values ('Creating SRR table...');
select top 0 * into temp.SRR from dbo.SRR (nolock);
create clustered columnstore index ix_SRR on temp.SRR with (online = off);
create index ix_SRR_JobId on temp.SRR (JobId);
insert Logs(Message) values('Populating SRR table...');
insert into temp.SRR with (tablock) select * from dbo.SRR (nolock);
insert Logs(Message) values ('Switching out SRR table...');
alter schema old transfer dbo.SRR;
alter schema dbo transfer temp.SRR;
insert Logs(Message) values ('SRR table converted.');
if (select count_big(*) from old.SRR (nolock)) = (select count_big(*) from dbo.SRR (nolock)) begin
drop table old.SRR;
insert Logs(Message) values('Deleted old SRR table.');
end else begin
insert Logs(Message) values('Row counts between old.SRR and dbo.SRR do not match; retaining old.SRR.');
end
Isso funcionou para todas as nossas outras grandes tabelas de relatórios, mas esta (após boas 30 horas de tempo de DTU) falha consistentemente com a mensagem:
Msg 40544, Level 17, State 2, Line 195
The database 'tempdb' has reached its size quota. Partition or delete data, drop indexes, or consult the documentation for possible resolutions.
O que posso fazer para que isso funcione?
A inserção em massa em um índice CLUSTERED COLUMNSTORE por si só não deve explodir o tempdb. As linhas são lidas e colocadas em rowgroups compactados em blocos de 1 milhão, não há motivo para o uso de tempdb de longo prazo.
Acredito que o problema seja o índice não clusterizado ix_SRR_JobId em temp.SRR (JobId);
Primeiro tente mover a criação do índice para após a inserção em massa:
Isso reduzirá substancialmente a pressão do tempdb.
Se o tempdb ainda estiver explodindo, tente carregar os dados em partes menores. Como você particiona os dados realmente não importa, mas deve ser baseado nas colunas principais de um índice clusterizado existente (exclusivo ou não). Os pedaços devem ser pequenos o suficiente para serem carregados, mas grandes o suficiente para evitar "grupos de linhas delta" excessivos ( Columnstore Indexes: Data Loading Guidance ).
Como ponto de partida, aponte para 10-20 pedaços de tamanho igual. Se a tabela base for de 2 TB, eles serão de 100 a 200 GB. Ajuste para cima ou para baixo até que funcione.
Por exemplo, se column1 for um datetime, tente carregar por ano, trimestre ou mês.