Deletes numa heap podem não reduzir nem o tamanho nem o número de reads

Esta é estranha… ou não.

Só quem nunca passou por ela é que duvida. Eu já passei por ela.

Estava a falar sobre isto com um colega que ainda não passou e que, naturalmente, duvidou.

Nada como mostrar que é possível.

Criamos uma tabela sem índice clustered, apenas um nonclustered. Heap mais simples não vão encontrar…

create table TesteHeap1
(	id bigint 
,	valor bigint
)
go

create nonclustered index nci_t on TesteHeap1 (id)
go

Inserimos alguns valores.

insert into TesteHeap1
select  ABS(CHECKSUM(NEWID()))
	,	ABS(CHECKSUM(NEWID()))
from sys.objects a
cross join sys.objects b

No meu caso, 24025 linhas.

Vamos ver o que temos por lá.

set statistics io, time on

select *
from TesteHeap1

75 logical reads para as 24025 linhas.

E tamanho?

exec sp_spaceused 'TesteHeap1'

Para já, nada de estranho.

Vamos a mais uns inserts?

insert into TesteHeap1
select  ABS(CHECKSUM(NEWID()))
	,	ABS(CHECKSUM(NEWID()))
from sys.objects a
cross join sys.objects b

E agora fazemos um delete.

delete 
from TesteHeap1
where valor > 100000

Aqui no meu caso “foram-se” 48047 linhas. Com o que é que ficámos?

3 linhas! E quantos reads?

18 reads para as 3 linhas. Tanto para tão pouco, não acham?

E espaço?

exec sp_spaceused 'TesteHeap1'

Tanto para tão pouco, não acham (v2) ?

Mais uma rodada de inserts.

insert into TesteHeap1
select  ABS(CHECKSUM(NEWID()))
	,	ABS(CHECKSUM(NEWID()))
from sys.objects a
cross join sys.objects b
select * from TesteHeap1
exec sp_spaceused 'TesteHeap1'

Mais 3 linhas do que na primeira vez e um pouco mais espaço também.

É só mais uma para o caminho…

insert into TesteHeap1
select  ABS(CHECKSUM(NEWID()))
	,	ABS(CHECKSUM(NEWID()))
from sys.objects a
cross join sys.objects b
select * from TesteHeap1
exec sp_spaceused 'TesteHeap1'
delete 
from TesteHeap1
where valor > 1000000000

Apagámos 25816 linhas… com o que é que ficamos?

select * from TesteHeap1
exec sp_spaceused 'TesteHeap1'

Analizando os dados depois do 1º insert e agora depois deste delete…

linhasreadsdataindexunusedreserved
1º insert2402575600K552K208K1360K
Agora222371581264K1576K404K3280K

Ou seja, menos dados, mais páginas, mais espaço.

Para referência, o que acontecerá se apagarmos todas as linhas?

A tabela vai ficar vazia… será?

delete
from TesteHeap1
exec sp_spaceused 'TesteHeap1'

Mesmo “vazia” não está vazia, claramente.

E com um REBUILD?

alter table TesteHeap1 rebuild
select * from TesteHeap1
exec sp_spaceused 'TesteHeap1'

Finalmente está “vazia”.

Agora não se metam a fazer REBUILD a todas as vossas heaps em PROD, ok?

Share

You may also like...

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *