{"id":1323,"date":"2012-02-29T08:09:19","date_gmt":"2012-02-29T10:09:19","guid":{"rendered":"http:\/\/fabriciolima.net\/blog\/?p=1323"},"modified":"2016-07-24T09:50:52","modified_gmt":"2016-07-24T12:50:52","slug":"colunas-com-valores-null-ocupam-espaco-em-disco-mito","status":"publish","type":"post","link":"https:\/\/fabriciolima.net\/blog\/2012\/02\/29\/colunas-com-valores-null-ocupam-espaco-em-disco-mito\/","title":{"rendered":"Colunas com valores NULL ocupam espa\u00e7o em disco? Mito?"},"content":{"rendered":"<p>Ol\u00e1 Pessoal,<\/p>\n<p>Muitos de voc\u00eas j\u00e1 devem ter recebido a seguinte solicita\u00e7\u00e3o: &#8220;<strong>Favor criar uma coluna nova na tabela X (80 milh\u00f5es de linhas). Como os valores existentes ser\u00e3o NULLs, esse campo n\u00e3o ocupar\u00e1 espa\u00e7o em disco e n\u00e3o teremos nenhum impacto nessa tabela<\/strong>&#8220;.<\/p>\n<p>Entretanto, n\u00e3o \u00e9 exatamente isso que acontece!<\/p>\n<p>Tipos de dados que possuem um tamanho fixo ocupam espa\u00e7o em disco mesmo sendo NULL. Ex: Int, bigint, char, datetime e etc..<\/p>\n<p>Tipos de dados que possuem um tamanho vari\u00e1vel, n\u00e3o ocupam espa\u00e7o em disco quando NULL . Ex: Varchar(100). Com exce\u00e7\u00e3o dos 2 bytes que o tipo varchar j\u00e1 ocupa inicialmente.<\/p>\n<p>Voc\u00ea pode verificar isso criando duas tabelas com as mesmas colunas, mas inserindo somente valores NULLs em uma tabela e somente valores n\u00e3o NULLs em outra tabela:<\/p>\n<p>create table Teste_NULL(<br \/>\nId int identity(1,1),<br \/>\nTesteInt int NULL,<br \/>\nTesteData datetime,<br \/>\nTesteChar char(10),<br \/>\nTesteNumeric numeric(15,2),<br \/>\nconstraint PK_Teste_NULL primary key (Id))<\/p>\n<p>create table Teste_NOTNULL(<br \/>\nId int identity(1,1),<br \/>\nTesteInt int NOT NULL,<br \/>\nTesteData datetime NOT NULL,<br \/>\nTesteChar char(10) NOT NULL,<br \/>\nTesteNumeric numeric(15,2) NOT NULL,<br \/>\nconstraint PK_Teste_NOTNULL primary key(Id))<\/p>\n<p>SET NOCOUNT ON<br \/>\n&#8212; Fiz um loop para funcionar em qualquer vers\u00e3o do SQL Server<br \/>\ndeclare @loop int<br \/>\nset @loop= 1<br \/>\nwhile @loop&lt;= 20000<br \/>\nbegin<br \/>\ninsert into Teste_NULL<br \/>\nselect null,null,null,null<\/p>\n<p>insert into Teste_NOTNULL<br \/>\nselect @loop,getdate(),&#8217;1234567890&#8242;, 9999999999999.99<br \/>\nset @loop= @loop + 1<br \/>\nend<\/p>\n<p>exec sp_spaceused Teste_NULL<br \/>\nexec sp_spaceused Teste_NOTNULL<\/p>\n<p>Essa query acima gera o resultado:<\/p>\n<p style=\"text-align: center;\"><a href=\"https:\/\/www.fabriciolima.net\/blog\/wp-content\/uploads\/2012\/02\/spaceusedTabelas.png\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1324\" title=\"spaceusedTabelas\" src=\"https:\/\/www.fabriciolima.net\/blog\/wp-content\/uploads\/2012\/02\/spaceusedTabelas.png\" alt=\"\" width=\"435\" height=\"189\" srcset=\"https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2012\/02\/spaceusedTabelas.png 402w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2012\/02\/spaceusedTabelas-300x131.png 300w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2012\/02\/spaceusedTabelas-100x44.png 100w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2012\/02\/spaceusedTabelas-275x120.png 275w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2012\/02\/spaceusedTabelas-20x9.png 20w\" sizes=\"auto, (max-width: 435px) 100vw, 435px\" \/><\/a><\/p>\n<p>Conforme pode ser visto, as duas tabelas possuem 20.000 linhas e ocupam o mesmo espa\u00e7o em disco. Logo, est\u00e1 provado que colunas com valores NULL tamb\u00e9m ocupam espa\u00e7o em disco.<\/p>\n<p>Entretanto, ao adicionarmos um campo em uma tabela existente, o sql server n\u00e3o aumenta o espa\u00e7o em disco ocupado por essa tabela.<\/p>\n<p>Visualizando:<\/p>\n<p>ALTER TABLE Teste_NULL<br \/>\nAdd Novacoluna datetime NULL<\/p>\n<p>Conferindo o tamanho da tabela Teste_NULL, podemos verificar que o mesmo n\u00e3o foi alterado:<\/p>\n<p><a href=\"https:\/\/www.fabriciolima.net\/blog\/wp-content\/uploads\/2012\/02\/spaceusedTabelas2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1325\" title=\"spaceusedTabelas2\" src=\"https:\/\/www.fabriciolima.net\/blog\/wp-content\/uploads\/2012\/02\/spaceusedTabelas2.png\" alt=\"\" width=\"378\" height=\"104\" srcset=\"https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2012\/02\/spaceusedTabelas2.png 378w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2012\/02\/spaceusedTabelas2-300x83.png 300w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2012\/02\/spaceusedTabelas2-100x28.png 100w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2012\/02\/spaceusedTabelas2-275x76.png 275w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2012\/02\/spaceusedTabelas2-20x6.png 20w\" sizes=\"auto, (max-width: 378px) 100vw, 378px\" \/><\/a><\/p>\n<p>Ent\u00e3o isso \u00e9 uma exce\u00e7\u00e3o e o SQL Server n\u00e3o ocupa espa\u00e7o em disco quando criamos esse campo???<\/p>\n<p>N\u00e3o \u00e9 bem assim. O SQL Server cria o seu novo campo apenas nos metadados, mas ele n\u00e3o percorre todas as p\u00e1ginas de dados alterando o tamanho das linhas da tabela para a inclus\u00e3o desse novo campo. Como n\u00f3s criamos campos no meio do dia (em zero segundos), essa opera\u00e7\u00e3o seria muito custosa de ser realizada.<\/p>\n<p>Contudo, ao realizarmos um REBUILD do \u00edndice clustered dessa tabela, o SQL Server recria as p\u00e1ginas de dados dessa tabela e nesse momento ele j\u00e1 deixa um espa\u00e7o reservado para essa nova coluna. Agora, sua coluna com valores NULL passa a ocupar espa\u00e7o em disco novamente.<\/p>\n<p>Visualizando:<\/p>\n<p>ALTER INDEX PK_Teste_NULL on Teste_NULL REBUILD<\/p>\n<p><a href=\"https:\/\/www.fabriciolima.net\/blog\/wp-content\/uploads\/2012\/02\/spaceusedTabelas3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1326\" title=\"spaceusedTabelas3\" src=\"https:\/\/www.fabriciolima.net\/blog\/wp-content\/uploads\/2012\/02\/spaceusedTabelas3.png\" alt=\"\" width=\"386\" height=\"108\" srcset=\"https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2012\/02\/spaceusedTabelas3.png 386w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2012\/02\/spaceusedTabelas3-300x84.png 300w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2012\/02\/spaceusedTabelas3-100x28.png 100w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2012\/02\/spaceusedTabelas3-275x77.png 275w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2012\/02\/spaceusedTabelas3-20x6.png 20w\" sizes=\"auto, (max-width: 386px) 100vw, 386px\" \/><\/a><\/p>\n<p>Como podem perceber, agora a nova coluna do tipo datetime e com valores somente NULL passou a ocupar espa\u00e7o em disco.<\/p>\n<p>Espero que tenha ajudado a esclarecer esse mito que \u00e9 comum de ouvirmos no nosso dia a dia.<\/p>\n<p><b>Gostou desse Post?<\/b><\/p>\n<p>Cadastre seu e-mail para receber novos Posts e curta minha <a href=\"https:\/\/www.facebook.com\/FabricioLimaSolucoesemBancodeDados\/\" target=\"_blank\">P\u00e1gina no Facebook<\/a> para receber Dicas de Leituras e Eventos sobre SQL Server.<\/p>\n<p>Abra\u00e7os,<\/p>\n<p>Fabr\u00edcio Lima<\/p>\n<p>MCITP \u2013 Database Administrator<\/p>\n<p>Consultor e Instrutor SQL Server<\/p>\n<p>Trabalha com SQL Server desde 2006<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ol\u00e1 Pessoal, Muitos de voc\u00eas j\u00e1 devem ter recebido a seguinte solicita\u00e7\u00e3o: &#8220;Favor criar uma coluna nova na tabela X (80 milh\u00f5es de linhas). Como os valores existentes ser\u00e3o NULLs, esse campo n\u00e3o ocupar\u00e1 espa\u00e7o em disco e n\u00e3o teremos nenhum impacto nessa tabela&#8220;. Entretanto, n\u00e3o \u00e9 exatamente isso que acontece! Tipos de dados que [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[3,6,280],"tags":[90,594,595,596,93,23,91,598,600,602,601,599,33,597],"class_list":["post-1323","post","type-post","status-publish","format-standard","hentry","category-administracao-de-bd","category-casos-do-dia-a-dia","category-virtual-pass-br","tag-alter-table","tag-campos-null","tag-campos-null-ocupam-espaco","tag-colunas-null-ocupam-espaco","tag-create-table","tag-dba","tag-espaco-em-disco","tag-espaco-em-disco-com-null","tag-mito","tag-mito-sql","tag-mitos-sql-server","tag-null","tag-sql-server","tag-valores-null-ocupam-espaco"],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":484,"url":"https:\/\/fabriciolima.net\/blog\/2011\/02\/26\/qual-o-valor-ideal-para-o-fillfactor-de-um-indice\/","url_meta":{"origin":1323,"position":0},"title":"Qual o valor ideal para o FILLFACTOR de um \u00cdndice?","author":"Fabr\u00edcio Lima","date":"26 de fevereiro de 2011","format":false,"excerpt":"Fala Pessoal, Voc\u00ea que \u00e9 um DBA, algum dia j\u00e1 deve ter feito essa pergunta para algu\u00e9m ou para o google. A resposta deve ter sido que n\u00e3o existe uma receita de bolo para definir o valor do fillfactor de um \u00edndice, seu valor depende do ambiente ser OLTP (Online\u2026","rel":"","context":"Em &quot;Administra\u00e7\u00e3o de Banco de Dados&quot;","block_context":{"text":"Administra\u00e7\u00e3o de Banco de Dados","link":"https:\/\/fabriciolima.net\/blog\/category\/sql-server\/administracao-de-bd\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.fabriciolima.net\/blog\/wp-content\/uploads\/2011\/02\/Tabela-Historico-Fragmentacao-300x90.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":285,"url":"https:\/\/fabriciolima.net\/blog\/2010\/03\/24\/criando-um-checklist-automatico-do-banco-de-dados\/","url_meta":{"origin":1323,"position":1},"title":"Criando um CheckList Autom\u00e1tico do Banco de Dados","author":"Fabr\u00edcio Lima","date":"24 de mar\u00e7o de 2010","format":false,"excerpt":"Atualizado em: 01\/05\/2017 OBS: Segue abaixo o link de um Post com uma nova vers\u00e3o desse CheckList muito mais pr\u00e1tica e com diversas melhorias. Desta vez, o CheckList ser\u00e1 enviado por e-mail em formato HTML: Link Post: Criando um E-mail de CheckList Di\u00e1rio no SQL Server \u00a0 Ol\u00e1 pessoal, Assim\u2026","rel":"","context":"Em &quot;Administra\u00e7\u00e3o de Banco de Dados&quot;","block_context":{"text":"Administra\u00e7\u00e3o de Banco de Dados","link":"https:\/\/fabriciolima.net\/blog\/category\/sql-server\/administracao-de-bd\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":169,"url":"https:\/\/fabriciolima.net\/blog\/2010\/11\/30\/casos-do-dia-a-dia-exclusao-de-um-indice-grande-e-pouco-utilizado\/","url_meta":{"origin":1323,"position":2},"title":"Casos do Dia a Dia &#8211; Exclus\u00e3o de um \u00edndice grande e pouco utilizado","author":"Fabr\u00edcio Lima","date":"30 de novembro de 2010","format":false,"excerpt":"Fala pessoal, Algum tempo atr\u00e1s, compartilhei uma experi\u00eancia que tive no Blog do Fabr\u00edcio Catae (Blog|Twitter), mas tamb\u00e9m resolvi deixar registrado por aqui. Muitos de voc\u00eas j\u00e1 utilizaram a dmv sys.dm_db_index_usage_stats para verificar a utiliza\u00e7\u00e3o e atualiza\u00e7\u00e3o dos \u00edndices de uma tabela. Tamb\u00e9m sabemos que essa dmv tem seus dados\u2026","rel":"","context":"Em &quot;Administra\u00e7\u00e3o de Banco de Dados&quot;","block_context":{"text":"Administra\u00e7\u00e3o de Banco de Dados","link":"https:\/\/fabriciolima.net\/blog\/category\/sql-server\/administracao-de-bd\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":133,"url":"https:\/\/fabriciolima.net\/blog\/2010\/10\/15\/casos-do-dia-a-dia-exclusao-de-campo-text-nao-libera-espaco-em-disco\/","url_meta":{"origin":1323,"position":3},"title":"Casos do Dia a Dia: Exclus\u00e3o de campo Text n\u00e3o libera espa\u00e7o em disco?","author":"Fabr\u00edcio Lima","date":"15 de outubro de 2010","format":false,"excerpt":"Fala pessoal, Compartilhando mais uma experi\u00eancia que tive no meu dia a dia de trabalho, ap\u00f3s a verifica\u00e7\u00e3o com a equipe de desenvolvimento da possibilidade de exclus\u00e3o de 2 campos do tipo text de uma tabela muito utilizada, fui com toda empolga\u00e7\u00e3o na minha base de testes verificar o quanto\u2026","rel":"","context":"Em &quot;Administra\u00e7\u00e3o de Banco de Dados&quot;","block_context":{"text":"Administra\u00e7\u00e3o de Banco de Dados","link":"https:\/\/fabriciolima.net\/blog\/category\/sql-server\/administracao-de-bd\/"},"img":{"alt_text":"spaceused_antes","src":"https:\/\/i0.wp.com\/www.fabriciolima.net\/blog\/wp-content\/uploads\/2010\/10\/spaceused_antes_thumb.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":928,"url":"https:\/\/fabriciolima.net\/blog\/2011\/08\/11\/como-monitorar-o-page-split-de-um-indice\/","url_meta":{"origin":1323,"position":4},"title":"Como monitorar o Page Split de um \u00cdndice?","author":"Fabr\u00edcio Lima","date":"11 de agosto de 2011","format":false,"excerpt":"Fala Pessoal, H\u00e1 um tempo atr\u00e1s, dando uma vasculhada na internet a procura de como monitorar Page Split no meu Banco de Dados(SQL SERVER 2005), encontrei uma query EXCEPCIONAL em v\u00e1rios artigos em ingl\u00eas, mas tamb\u00e9m encontrei um artigo em portugu\u00eas do Laerte J\u00fanior(Twitter) que fala sobre o assunto: O\u2026","rel":"","context":"Em &quot;Administra\u00e7\u00e3o de Banco de Dados&quot;","block_context":{"text":"Administra\u00e7\u00e3o de Banco de Dados","link":"https:\/\/fabriciolima.net\/blog\/category\/sql-server\/administracao-de-bd\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2313,"url":"https:\/\/fabriciolima.net\/blog\/2013\/08\/26\/casos-do-dia-a-dia-trigger-para-descobrir-como-um-registro-e-inserido-alterado-e-deletado\/","url_meta":{"origin":1323,"position":5},"title":"Casos do Dia a Dia &#8211; Trigger para descobrir como um registro \u00e9 inserido, alterado e deletado","author":"Fabr\u00edcio Lima","date":"26 de agosto de 2013","format":false,"excerpt":"Fala Pessoal, Ap\u00f3s um longo tempo, segue mais um post com um caso do dia a dia que aconteceu comigo. Onde trabalho, estavam tentando descobrir o que estava alterando dados de uma tabela e como isso estava sendo feito. Uma das formas de fazer isso era criando um trace, contudo,\u2026","rel":"","context":"Em &quot;Administra\u00e7\u00e3o de Banco de Dados&quot;","block_context":{"text":"Administra\u00e7\u00e3o de Banco de Dados","link":"https:\/\/fabriciolima.net\/blog\/category\/sql-server\/administracao-de-bd\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.fabriciolima.net\/blog\/wp-content\/uploads\/2013\/08\/ResultadoTrigger.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.fabriciolima.net\/blog\/wp-content\/uploads\/2013\/08\/ResultadoTrigger.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.fabriciolima.net\/blog\/wp-content\/uploads\/2013\/08\/ResultadoTrigger.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.fabriciolima.net\/blog\/wp-content\/uploads\/2013\/08\/ResultadoTrigger.png?resize=700%2C400&ssl=1 2x"},"classes":[]}],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/posts\/1323","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/comments?post=1323"}],"version-history":[{"count":0,"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/posts\/1323\/revisions"}],"wp:attachment":[{"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/media?parent=1323"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/categories?post=1323"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/tags?post=1323"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}