{"id":8335,"date":"2026-03-11T13:00:37","date_gmt":"2026-03-11T16:00:37","guid":{"rendered":"https:\/\/powertuning.com.br\/?p=8335"},"modified":"2026-03-11T11:18:32","modified_gmt":"2026-03-11T14:18:32","slug":"quando-ghost-records-viram-um-problema-de-performance-no-sql-server","status":"publish","type":"post","link":"https:\/\/powertuning.com.br\/blog\/quando-ghost-records-viram-um-problema-de-performance-no-sql-server\/","title":{"rendered":"Quando Ghost Records viram um problema de performance no SQL Server!"},"content":{"rendered":"<p class=\"article-editor-paragraph article-editor-content__has-focus\">Recentemente analisamos um caso em produ\u00e7\u00e3o muito interessante. Um job que executava em cerca de <strong>5 minutos<\/strong>, passou a ficar cada dia mais lento at\u00e9 chegar a <strong>48 minutos<\/strong>.<\/p>\n<p class=\"article-editor-paragraph\">Sem altera\u00e7\u00f5es na rotina ou no ambiente que justificassem essa demora. Tentamos simular em base de <strong>HML<\/strong> e n\u00e3o estava sendo poss\u00edvel reproduzir o cen\u00e1rio. Sem waits que justificassem, tempo de processamento era <strong>+90% CPU<\/strong>, sem <strong>spinlocks<\/strong> com impactos diretos, fizemos diversos testes para entender a diferen\u00e7a em uma <strong>base c\u00f3pia<\/strong>.<\/p>\n<p class=\"article-editor-paragraph\">O processo era <strong>&#8220;complexo&#8221;<\/strong>. Muitos loops de <strong>DELETES<\/strong> faziam com que o plano de execu\u00e7\u00e3o n\u00e3o fosse gerado inteiro para conseguirmos comparar efetivamente.<\/p>\n<div class=\"article-editor-horizontal-rule__container\" contenteditable=\"false\">\n<hr class=\"article-editor-horizontal-rule\" \/>\n<div class=\"article-editor-horizontal-rule__delete-button-container\"><\/div>\n<\/div>\n<h3 class=\"article-editor-heading\">Primeiros testes<\/h3>\n<p class=\"article-editor-paragraph\">Ent\u00e3o decidimos simplificar as compara\u00e7\u00f5es entre os ambientes, e testamos um simples <strong>SELECT TOP (5000)<\/strong> na tabela que mais apresentava lentid\u00e3o no processo.<\/p>\n<p class=\"article-editor-paragraph\">Comparando os ambientes <strong>produtivo e HML<\/strong> teve uma grande diferen\u00e7a:<\/p>\n<ul class=\"article-editor-bullet-list\">\n<li class=\"article-editor-list-item\">\n<p class=\"article-editor-paragraph\"><strong>~2700ms em produ\u00e7\u00e3o<\/strong><\/p>\n<\/li>\n<li class=\"article-editor-list-item\">\n<p class=\"article-editor-paragraph\"><strong>16ms em HML<\/strong><\/p>\n<\/li>\n<\/ul>\n<p class=\"article-editor-paragraph\"><em>(tempo de CPU)<\/em><\/p>\n<p class=\"article-editor-paragraph\">Ambientes visualmente iguais, hardware equivalente, configura\u00e7\u00f5es similares, plano de execu\u00e7\u00e3o com os mesmos operadores e estimativas, estat\u00edsticas iguais\u2026 <strong>nada parecia diferente para justificar<\/strong>.<\/p>\n<div class=\"article-editor-horizontal-rule__container\" contenteditable=\"false\">\n<hr class=\"article-editor-horizontal-rule\" \/>\n<div class=\"article-editor-horizontal-rule__delete-button-container\"><\/div>\n<\/div>\n<h3 class=\"article-editor-heading\">Um comportamento curioso<\/h3>\n<p class=\"article-editor-paragraph\">Ap\u00f3s restaurar a base novamente para novos testes tivemos uma boa surpresa: a query demorou nas <strong>3 primeiras execu\u00e7\u00f5es<\/strong> e depois voltou a ficar com <strong>16ms nas demais<\/strong>.<\/p>\n<p class=\"article-editor-paragraph\">Apenas na primeira execu\u00e7\u00e3o teve <strong>leituras f\u00edsicas \/ read-ahead<\/strong>, ent\u00e3o n\u00e3o seria uma justificativa para as execu\u00e7\u00f5es subsequentes tamb\u00e9m terem <strong>tempo de CPU alto<\/strong>.<\/p>\n<p class=\"article-editor-paragraph\">Repetimos esse teste para pegar mais informa\u00e7\u00f5es e reparamos que <strong>a quantidade de leituras l\u00f3gicas come\u00e7ava alta e ca\u00eda aos poucos<\/strong>.<\/p>\n<div class=\"article-editor-horizontal-rule__container\" contenteditable=\"false\">\n<hr class=\"article-editor-horizontal-rule\" \/>\n<div class=\"article-editor-horizontal-rule__delete-button-container\"><\/div>\n<\/div>\n<h3 class=\"article-editor-heading\">O efeito do rebuild<\/h3>\n<p class=\"article-editor-paragraph\">Vimos que, com o <strong>REBUILD do \u00edndice cluster ap\u00f3s o restore<\/strong>, a consulta n\u00e3o apresentava mais lentid\u00e3o nas primeiras execu\u00e7\u00f5es. J\u00e1 iniciava com o tempo esperado de <strong>16ms<\/strong>.<\/p>\n<p class=\"article-editor-paragraph\">A <strong>fragmenta\u00e7\u00e3o do \u00edndice tamb\u00e9m n\u00e3o justificava os sintomas<\/strong>.<\/p>\n<p class=\"article-editor-paragraph\">A\u00ed come\u00e7ou uma nova busca para entender <strong>o que o rebuild resolve<\/strong>, impacta nas leituras l\u00f3gicas e <strong>n\u00e3o \u00e9 fragmenta\u00e7\u00e3o<\/strong>.<\/p>\n<p class=\"article-editor-paragraph\">Parece at\u00e9 uma <strong>charada<\/strong> rsrs.<\/p>\n<div class=\"article-editor-horizontal-rule__container\" contenteditable=\"false\">\n<hr class=\"article-editor-horizontal-rule\" \/>\n<div class=\"article-editor-horizontal-rule__delete-button-container\"><\/div>\n<\/div>\n<h3 class=\"article-editor-heading\">A hip\u00f3tese que explicou tudo<\/h3>\n<p class=\"article-editor-paragraph\">Conversando internamente com o time para ajudarem com ideias, a <strong>Raiane Flores Borba Lins<\/strong> deu v\u00e1rias ideias e hip\u00f3teses.<\/p>\n<p class=\"article-editor-paragraph\">Mas todas j\u00e1 haviam sido testadas e descartadas, <strong>menos a \u00faltima<\/strong>:<\/p>\n<p class=\"article-editor-paragraph\"><strong>&#8220;Ghost Records&#8221;<\/strong><\/p>\n<p class=\"article-editor-paragraph\">Algo que ainda n\u00e3o havia sido validado.<\/p>\n<p class=\"article-editor-paragraph\">Causaria os mesmos sintomas e <strong>seria resolvido com o rebuild<\/strong>.<\/p>\n<div class=\"article-editor-horizontal-rule__container\" contenteditable=\"false\">\n<hr class=\"article-editor-horizontal-rule\" \/>\n<div class=\"article-editor-horizontal-rule__delete-button-container\"><\/div>\n<\/div>\n<h3 class=\"article-editor-heading\">Valida\u00e7\u00e3o do cen\u00e1rio<\/h3>\n<p class=\"article-editor-paragraph\">Para conseguirmos comprovar, desativamos o processo do <strong>Ghost Cleanup<\/strong> em uma nova inst\u00e2ncia para testes.<\/p>\n<p class=\"article-editor-paragraph\">Subimos a base e conseguimos validar que <strong>a tabela tinha mais de 11 milh\u00f5es de ghost records<\/strong>.<\/p>\n<p class=\"article-editor-paragraph\">Algumas tabelas na base <strong>passavam de 40 milh\u00f5es<\/strong>.<\/p>\n<div class=\"article-editor-horizontal-rule__container\" contenteditable=\"false\">\n<hr class=\"article-editor-horizontal-rule\" \/>\n<div class=\"article-editor-horizontal-rule__delete-button-container\"><\/div>\n<\/div>\n<h3 class=\"article-editor-heading\">O que s\u00e3o Ghost Records<\/h3>\n<p class=\"article-editor-paragraph\">No <strong>SQL Server<\/strong>, quando um registro \u00e9 deletado, ele <strong>nem sempre \u00e9 removido fisicamente naquele momento<\/strong>.<\/p>\n<p class=\"article-editor-paragraph\">Muitas vezes ele \u00e9 apenas <strong>marcado para remo\u00e7\u00e3o futura<\/strong>, ficando como <strong>&#8220;ghost record&#8221;<\/strong>.<\/p>\n<p class=\"article-editor-paragraph\">A limpeza f\u00edsica \u00e9 feita periodicamente por um processo interno chamado <strong>Ghost Cleanup<\/strong>.<\/p>\n<div class=\"article-editor-horizontal-rule__container\" contenteditable=\"false\">\n<hr class=\"article-editor-horizontal-rule\" \/>\n<div class=\"article-editor-horizontal-rule__delete-button-container\"><\/div>\n<\/div>\n<h3 class=\"article-editor-heading\">O impacto na pr\u00e1tica<\/h3>\n<p class=\"article-editor-paragraph\">Na pr\u00e1tica, isso fazia uma consulta simples como:<\/p>\n<p class=\"article-editor-paragraph\"><strong>SELECT TOP (5000)<\/strong><\/p>\n<p class=\"article-editor-paragraph\">precisar percorrer <strong>dezenas de milhares de p\u00e1ginas<\/strong> para encontrar <strong>5.000 linhas v\u00e1lidas<\/strong>.<\/p>\n<p class=\"article-editor-paragraph\">O resultado foi:<\/p>\n<ul class=\"article-editor-bullet-list\">\n<li class=\"article-editor-list-item\">\n<p class=\"article-editor-paragraph\"><strong>alto volume de leituras l\u00f3gicas<\/strong><\/p>\n<\/li>\n<li class=\"article-editor-list-item\">\n<p class=\"article-editor-paragraph\"><strong>aumento de CPU<\/strong><\/p>\n<\/li>\n<\/ul>\n<p class=\"article-editor-paragraph\">\u00c0 medida que o <strong>Ghost Cleanup<\/strong> avan\u00e7ava, a mesma consulta passava a executar com <strong>poucas leituras e CPU praticamente zero<\/strong>.<\/p>\n<p class=\"article-editor-paragraph\">O mesmo efeito tamb\u00e9m foi validado com <strong>rebuild de \u00edndice<\/strong>, que reduziu drasticamente a quantidade de <strong>ghost records<\/strong> e devolveu a <strong>performance esperada<\/strong>.<\/p>\n<div class=\"article-editor-horizontal-rule__container\" contenteditable=\"false\">\n<hr class=\"article-editor-horizontal-rule\" \/>\n<div class=\"article-editor-horizontal-rule__delete-button-container\"><\/div>\n<\/div>\n<h3 class=\"article-editor-heading\">Por que o problema n\u00e3o apareceu antes<\/h3>\n<p class=\"article-editor-paragraph\">Uma caracter\u00edstica do <strong>Ghost Cleanup<\/strong> \u00e9 que, ap\u00f3s um <strong>scan na tabela ou \u00edndice<\/strong>, as ghost records s\u00e3o <strong>enfileiradas para que ele possa fazer a limpeza<\/strong>.<\/p>\n<p class=\"article-editor-paragraph\">Isso fez com que os testes iniciais em <strong>HML resolvessem o problema antes de conseguirmos identificar a causa<\/strong>, nos levando para outros caminhos.<\/p>\n<p class=\"article-editor-paragraph\">O cuidado do cliente em <strong>n\u00e3o permitir scans na tabela<\/strong> fez com que elas n\u00e3o fossem <strong>&#8220;for\u00e7adas&#8221; \u00e0 limpeza<\/strong>, entrando na fila padr\u00e3o concorrendo com <strong>milhares de outras<\/strong>.<\/p>\n<div class=\"article-editor-horizontal-rule__container\" contenteditable=\"false\">\n<hr class=\"article-editor-horizontal-rule\" \/>\n<div class=\"article-editor-horizontal-rule__delete-button-container\"><\/div>\n<\/div>\n<h3 class=\"article-editor-heading\">Algumas a\u00e7\u00f5es que podem ajudar nesse tipo de cen\u00e1rio<\/h3>\n<ul class=\"article-editor-bullet-list\">\n<li class=\"article-editor-list-item\">\n<p class=\"article-editor-paragraph\"><strong>manuten\u00e7\u00e3o peri\u00f3dica de \u00edndices<\/strong><\/p>\n<\/li>\n<li class=\"article-editor-list-item\">\n<p class=\"article-editor-paragraph\"><strong>reavaliar estrat\u00e9gia de deletes em batches maiores<\/strong><\/p>\n<\/li>\n<li class=\"article-editor-list-item\">\n<p class=\"article-editor-paragraph\"><strong>usar TRUNCATE quando aplic\u00e1vel<\/strong><\/p>\n<\/li>\n<li class=\"article-editor-list-item\">\n<p class=\"article-editor-paragraph\"><strong>em alguns casos, recriar a tabela e mover apenas os dados necess\u00e1rios<\/strong><\/p>\n<\/li>\n<li class=\"article-editor-list-item\">\n<p class=\"article-editor-paragraph\"><strong>for\u00e7ar scan das tabelas para for\u00e7ar o ghost cleanup (brincadeira rs, o rebuild ainda \u00e9 uma op\u00e7\u00e3o melhor)<\/strong><\/p>\n<\/li>\n<\/ul>\n<div class=\"article-editor-horizontal-rule__container\" contenteditable=\"false\">\n<hr class=\"article-editor-horizontal-rule\" \/>\n<div class=\"article-editor-horizontal-rule__delete-button-container\"><\/div>\n<\/div>\n<p class=\"article-editor-paragraph\"><strong>Est\u00e1 passando por esse tipo de problema na sua empresa? A Power Tuning oferece consultoria especializada em performance para Banco de Dados. <\/strong><\/p>\n<p class=\"article-editor-paragraph\"><strong>Fale com a gente: +55 27 3441-3060<\/strong><\/p>\n<p class=\"article-editor-paragraph\"><em>Artigo desenvolvido por: Eduardo Rabelo (Tech Leader).<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Recentemente analisamos um caso em produ\u00e7\u00e3o muito interessante. Um job que executava em cerca de 5 minutos, passou a ficar cada dia mais lento at\u00e9 chegar a 48 minutos. Sem altera\u00e7\u00f5es na rotina ou no ambiente que justificassem essa demora. Tentamos simular em base de HML e n\u00e3o estava sendo poss\u00edvel reproduzir o cen\u00e1rio. Sem&hellip; <br \/> <a class=\"read-more\" href=\"https:\/\/powertuning.com.br\/blog\/quando-ghost-records-viram-um-problema-de-performance-no-sql-server\/\">Leia mais<\/a><\/p>\n","protected":false},"author":17,"featured_media":8337,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"content-type":"","_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[176,62],"tags":[],"class_list":["post-8335","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-banco-de-dados","category-casos-reais-de-clientes"],"jetpack_featured_media_url":"https:\/\/powertuning.com.br\/blog\/wp-content\/uploads\/2026\/03\/Capa_Blog-2.png","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/powertuning.com.br\/blog\/wp-json\/wp\/v2\/posts\/8335","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/powertuning.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/powertuning.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/powertuning.com.br\/blog\/wp-json\/wp\/v2\/users\/17"}],"replies":[{"embeddable":true,"href":"https:\/\/powertuning.com.br\/blog\/wp-json\/wp\/v2\/comments?post=8335"}],"version-history":[{"count":1,"href":"https:\/\/powertuning.com.br\/blog\/wp-json\/wp\/v2\/posts\/8335\/revisions"}],"predecessor-version":[{"id":8338,"href":"https:\/\/powertuning.com.br\/blog\/wp-json\/wp\/v2\/posts\/8335\/revisions\/8338"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/powertuning.com.br\/blog\/wp-json\/wp\/v2\/media\/8337"}],"wp:attachment":[{"href":"https:\/\/powertuning.com.br\/blog\/wp-json\/wp\/v2\/media?parent=8335"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/powertuning.com.br\/blog\/wp-json\/wp\/v2\/categories?post=8335"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/powertuning.com.br\/blog\/wp-json\/wp\/v2\/tags?post=8335"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}