{"id":440,"date":"2011-02-16T20:59:11","date_gmt":"2011-02-16T22:59:11","guid":{"rendered":"http:\/\/fabriciolima.net\/blog\/?p=440"},"modified":"2017-03-23T18:24:39","modified_gmt":"2017-03-23T21:24:39","slug":"monitorando-a-fragmentacao-dos-indices","status":"publish","type":"post","link":"https:\/\/fabriciolima.net\/blog\/2011\/02\/16\/monitorando-a-fragmentacao-dos-indices\/","title":{"rendered":"Monitorando a fragmenta\u00e7\u00e3o dos \u00edndices"},"content":{"rendered":"<p>Um dos grandes problemas que temos com rela\u00e7\u00e3o a performance \u00e9 devido a fragmenta\u00e7\u00e3o de nossos \u00edndices. Com o grande n\u00famero de inser\u00e7\u00f5es, altera\u00e7\u00f5es e exclus\u00f5es que ocorrem em nossas tabelas, os \u00edndices se fragmentam cada vez mais, ocasionando uma lentid\u00e3o na manipula\u00e7\u00e3o dos dados desses \u00edndices.<\/p>\n<p>Como voc\u00ea resolveria esse problema de fragmenta\u00e7\u00e3o?<\/p>\n<p><strong>R:<\/strong> Essa \u00e9 f\u00e1cil Fabr\u00edcio, criando uma rotina peri\u00f3dica que executa os procedimentos de REBUILD ou REORGANIZE para os meus \u00edndices.<\/p>\n<p>Exato, mas com que frequencia voc\u00ea rodaria essa rotina? Quais as tabelas que precisam ter seus \u00edndices desfragmentados com uma maior frequ\u00eancia?<\/p>\n<p>Imagina que voc\u00ea possua muitas tabelas com milhares de registros e s\u00f3 tenha uma janela de 1 hora para desfragmentar todos os seus \u00edndices. Voce ter\u00e1 que dividir a desfragmenta\u00e7\u00e3o dos \u00edndices em v\u00e1rios dias al\u00e9m de tamb\u00e9m definir a frequ\u00eancia com que os \u00edndices ser\u00e3o reorganizados ou reconstru\u00eddos.<\/p>\n<p>Esse \u00e9 exatamente o ambiente que possuo, com muitas tabelas grandes e com apenas uma hora de janela para realizar esse procedimento.<\/p>\n<p>Digamos que eu possua 100 tabelas em uma determinada database, desfragmentar as 80 menores tabelas demoram 40 minutos, outras 10 tabelas juntas demoram 50 min, outras 5 tabelas juntas demoram 45 minutos, 3 tabelas demoram 40 minutos e 2 tabelas demoram 50 minutos.<\/p>\n<p>Nessa situa\u00e7\u00e3o, eu criaria 5 jobs de manuten\u00e7\u00e3o dos \u00edndices:<\/p>\n<ul>\n<li>Job 1 &#8211; 80 tabelas<\/li>\n<li>Job 2 &#8211; 10 tabelas<\/li>\n<li>Job 3 &#8211; 5 tabelas<\/li>\n<li>Job 4 &#8211; 3 Tabelas<\/li>\n<li>Job 5 &#8211; 2 Tabelas<\/li>\n<\/ul>\n<p>Mas como eu saberia com que frequ\u00eancia rodar cada um desses jobs?<\/p>\n<p>Para definir essa frequ\u00eancia, eu utilizo uma rotina que armazena diariamente a fragmenta\u00e7\u00e3o de todos os \u00edndices de minhas principais databases. Como a query para verificar a fragmenta\u00e7\u00e3o dos \u00edndices \u00e9 um pouco custosa, eu utilizo um servidor D-1 que recebe um restore di\u00e1rio das bases de produ\u00e7\u00e3o para executar esse procedimento. Caso voc\u00ea n\u00e3o possua um servidor D-1 voc\u00ea deve agendar um job para executar esse procedimento em um hor\u00e1rio de pouco movimento.<\/p>\n<p>Inicialmente, devemos criar uma tabela que armazenar\u00e1 nosso hist\u00f3rico de fragmenta\u00e7\u00e3o.<\/p>\n<pre class=\"lang:tsql decode:true \">CREATE TABLE [dbo].[Hitorico_Fragmentacao_Indice](\r\n[Id_Hitorico_Fragmentacao_Indice] [int] IDENTITY(1,1) NOT NULL,\r\n[Dt_Referencia] [datetime] NULL,\r\n[Nm_Servidor] [varchar](50) NULL,\r\n[Nm_Database] [varchar](50) NULL,\r\n[Nm_Tabela] [varchar](50) NULL,\r\n[Nm_Indice] [varchar](70) NULL,\r\n[Avg_Fragmentation_In_Percent] [numeric](5, 2) NULL,\r\n[Page_Count] [int] NULL,\r\n[Fill_Factor] [tinyint] NULL)\r\n<\/pre>\n<p>Para popular essa tabela, basta rodar a query abaixo que\u00a0retorna a fragmenta\u00e7\u00e3o de todos os \u00edndices da database em que ela est\u00e1 sendo executada.<\/p>\n<pre class=\"lang:tsql decode:true \">INSERT INTO\u00a0Hitorico_Fragmentacao_Indice(Dt_Referencia,Nm_Servidor,Nm_Database,Nm_Tabela,Nm_Indice,Avg_Fragmentation_In_Percent,\r\nPage_Count,Fill_Factor)\r\nSELECT getdate(), @@servername,\u00a0 db_name(db_id()), object_name(B.Object_id), B.Name,\u00a0 avg_fragmentation_in_percent,page_Count,fill_factor\r\nFROM sys.dm_db_index_physical_stats(db_id(),null,null,null,null) A\r\njoin sys.indexes B on a.object_id = B.Object_id and A.index_id = B.index_id\r\nORDER BY object_name(B.Object_id), B.index_id\r\n<\/pre>\n<p><strong>OBS: Lembrando que essa \u00e9 a query demorada e deve ser executada em um hor\u00e1rio de pouco movimento do banco de dados.<\/strong><\/p>\n<p>Com essa importante informa\u00e7\u00e3o sendo armazenada no banco de dados, recebo no meu <a title=\"criando-um-checklist-automatico-do-banco-de-dados\/\" href=\"https:\/\/www.fabriciolima.net\/blog\/2010\/03\/24\/criando-um-checklist-automatico-do-banco-de-dados\/\" target=\"_blank\">CheckList di\u00e1rio do banco de dados<\/a> um relat\u00f3rio\u00a0de todos os \u00edndices que est\u00e3o com uma fragmenta\u00e7\u00e3o maior que 5% e consigo identificar os \u00edndices que mais est\u00e3o se fragmentando para analisar um poss\u00edvel aumento na frequ\u00eancia do job de desfragmenta\u00e7\u00e3o.<\/p>\n<p>Segue abaixo a query que gera os dados para a planilha:<\/p>\n<pre class=\"lang:tsql decode:true\">declare @Dt_Referencia datetime\r\nset @Dt_Referencia = cast(floor(cast( getdate() as float)) as datetime)\r\n\r\nSELECT Nm_Servidor, Nm_Database, Nm_Tabela, Nm_Indice, Avg_Fragmentation_In_Percent, Page_Count, Fill_Factor\r\nFROM\u00a0Hitorico_Fragmentacao_Indice (nolock)\r\nWHERE\u00a0Avg_Fragmentation_In_Percent &gt; 5\r\nAND page_count &gt; 1000 \u00a0\u00a0-- Eliminar \u00edndices pequenos\r\nAND Dt_Referencia &gt;= @Dt_Referencia\r\n<\/pre>\n<p>Essa query retorna o seguinte resultado:<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-7641 aligncenter\" src=\"https:\/\/www.fabriciolima.net\/blog\/wp-content\/uploads\/2011\/02\/Fragmentacao_Indice-1.png\" alt=\"\" width=\"923\" height=\"85\" srcset=\"https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2011\/02\/Fragmentacao_Indice-1.png 923w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2011\/02\/Fragmentacao_Indice-1-300x28.png 300w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2011\/02\/Fragmentacao_Indice-1-768x71.png 768w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2011\/02\/Fragmentacao_Indice-1-700x64.png 700w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2011\/02\/Fragmentacao_Indice-1-410x38.png 410w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2011\/02\/Fragmentacao_Indice-1-100x9.png 100w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2011\/02\/Fragmentacao_Indice-1-275x25.png 275w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2011\/02\/Fragmentacao_Indice-1-20x2.png 20w\" sizes=\"auto, (max-width: 923px) 100vw, 923px\" \/><\/p>\n<p>Quando a fragmenta\u00e7\u00e3o de algum \u00edndice ultrapassa 15%, essa linha ja vem\u00a0vermelha e em negrito na minha planilha de CheckList.<\/p>\n<p>Devido a facilidade de implementa\u00e7\u00e3o dessa rotina (para quem possui uma janela de execu\u00e7\u00e3o), acredito que seria bem interessante guardar essa informa\u00e7\u00e3o e aumentar a baseline do seu banco de dados.<\/p>\n<p>Al\u00e9m disso, no meu pr\u00f3ximo post mostrarei como essa informa\u00e7\u00e3o me ajuda a definir o valor do FILL FACTOR de minhas tabelas.<\/p>\n<p>&nbsp;<\/p>\n<p><b>Gostou dessa Dica?<\/b><\/p>\n<p>Curta, comente, compartilhe\u2026<\/p>\n<p>Assine meu canal no <a href=\"https:\/\/www.youtube.com\/channel\/UCeBRAO_LLrUdSrOXIywjzRA\" target=\"_blank\">Youtube<\/a> e curta minha p\u00e1gina no <a class=\"external-link wpel-icon-left\" href=\"https:\/\/www.facebook.com\/FabricioLimaSolucoesemBancodeDados\/\" target=\"_blank\" rel=\"nofollow external noopener noreferrer\" data-wpel-link=\"external\">Facebook<\/a> para receber Dicas de Leituras, V\u00eddeos e Eventos sobre SQL Server.<\/p>\n<p>Aprenda a criar essa e outras rotinas para administrar melhor seu SQL Server no meu <a href=\"https:\/\/www.fabriciolima.net\/cursos-online\/treinamento-tarefas-do-dia-a-dia-de-um-dba-online\/\" target=\"_blank\">Treinamento de Tarefas do Dia a Dia de um DBA<\/a>.<\/p>\n<p>At\u00e9 a pr\u00f3xima.<\/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>Um dos grandes problemas que temos com rela\u00e7\u00e3o a performance \u00e9 devido a fragmenta\u00e7\u00e3o de nossos \u00edndices. Nesse post mostro como criar uma rotina para monitorar a fragmenta\u00e7\u00e3o dos \u00edndices do Banco de Dados e diminuir essa fragmenta\u00e7\u00e3o.<\/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":""},"categories":[3,280],"tags":[191,23,186,192,184,110,89,188,49,33,193,40],"class_list":["post-440","post","type-post","status-publish","format-standard","hentry","category-administracao-de-bd","category-virtual-pass-br","tag-checklist-do-banco-de-dados","tag-dba","tag-desfragmentar-um-indice","tag-fill-factor","tag-fragmentacao-de-indices","tag-indice","tag-rebuild","tag-reorganize","tag-sql","tag-sql-server","tag-tamanho-fill-factor","tag-tuning"],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/posts\/440","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=440"}],"version-history":[{"count":0,"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/posts\/440\/revisions"}],"wp:attachment":[{"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/media?parent=440"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/categories?post=440"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/tags?post=440"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}