{"id":8718,"date":"2018-02-07T09:56:18","date_gmt":"2018-02-07T11:56:18","guid":{"rendered":"http:\/\/www.fabriciolima.net\/?p=8718"},"modified":"2020-10-10T14:29:17","modified_gmt":"2020-10-10T17:29:17","slug":"melhorando-a-performance-de-consultas-no-totvs-protheus-parte-7","status":"publish","type":"post","link":"https:\/\/fabriciolima.net\/blog\/2018\/02\/07\/melhorando-a-performance-de-consultas-no-totvs-protheus-parte-7\/","title":{"rendered":"Melhorando a Performance de Consultas no Totvs Protheus &#8211; Parte 7"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-8787 aligncenter\" src=\"https:\/\/www.fabriciolima.net\/blog\/wp-content\/uploads\/2018\/02\/fimnetflix.png\" alt=\"\" width=\"353\" height=\"333\" srcset=\"https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/02\/fimnetflix.png 700w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/02\/fimnetflix-300x283.png 300w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/02\/fimnetflix-410x387.png 410w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/02\/fimnetflix-100x94.png 100w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/02\/fimnetflix-275x260.png 275w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/02\/fimnetflix-20x20.png 20w\" sizes=\"auto, (max-width: 353px) 100vw, 353px\" \/><\/p>\n<p>Fala pessoal,<\/p>\n<p>Como tudo que \u00e9 bom dura, pouco, esse \u00e9 o \u00faltimo epis\u00f3dio da nossa s\u00e9rie de artigos de Tuning de consultas no Totvs Protheus.<\/p>\n<p>Lembrando que essas dicas valem para queries de outros sistemas tamb\u00e9m.<\/p>\n<p>Antes de lerem esse post, caso ainda n\u00e3o tenham lido os anteriores, sugiro que fa\u00e7am para seguirem a linha de racioc\u00ednio:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.fabriciolima.net\/blog\/2017\/12\/11\/melhorando-a-performance-de-consultas-no-totvs-protheus-parte-1\/\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/www.fabriciolima.net\/blog\/2017\/12\/11\/melhorando-a-performance-de-consultas-no-totvs-protheus-parte-1\/<\/a><\/li>\n<li><a href=\"https:\/\/www.fabriciolima.net\/blog\/2017\/12\/18\/melhorando-a-performance-de-consultas-no-totvs-protheus-parte-2\/\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/www.fabriciolima.net\/blog\/2017\/12\/18\/melhorando-a-performance-de-consultas-no-totvs-protheus-parte-2\/<\/a><\/li>\n<li><a href=\"https:\/\/www.fabriciolima.net\/blog\/2018\/01\/08\/melhorando-a-performance-de-consultas-no-totvs-protheus-parte-3\/\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/www.fabriciolima.net\/blog\/2018\/01\/08\/melhorando-a-performance-de-consultas-no-totvs-protheus-parte-3\/<\/a><\/li>\n<li><a href=\"https:\/\/www.fabriciolima.net\/blog\/2018\/01\/16\/melhorando-a-performance-de-consultas-no-totvs-protheus-parte-4\/\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/www.fabriciolima.net\/blog\/2018\/01\/16\/melhorando-a-performance-de-consultas-no-totvs-protheus-parte-4\/<\/a><\/li>\n<li><a href=\"https:\/\/www.fabriciolima.net\/blog\/2018\/01\/23\/melhorando-a-performance-de-consultas-no-totvs-protheus-parte-5\/\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/www.fabriciolima.net\/blog\/2018\/01\/23\/melhorando-a-performance-de-consultas-no-totvs-protheus-parte-5\/<\/a><\/li>\n<li><a href=\"https:\/\/www.fabriciolima.net\/blog\/2018\/01\/30\/melhorando-a-performance-de-consultas-no-totvs-protheus-parte-6\/\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/www.fabriciolima.net\/blog\/2018\/01\/30\/melhorando-a-performance-de-consultas-no-totvs-protheus-parte-6\/<\/a><\/li>\n<\/ul>\n<p>Analisando mais umas das queries que demoram mais de 3 segundos em um cliente:<\/p>\n<pre class=\"lang:tsql decode:true\">SELECT Z6_RETORNO AS 'DIRETOR',\r\n       ZV_DESCRIC AS 'REGIONAL',\r\n       ZM_EMP,\r\n       RE0_FILIAL AS 'FILIAL',\r\n       CASE\r\n           WHEN RE0_RECLAM = 'VARIOS' THEN\r\n               'VARIOS'\r\n           ELSE\r\n               RD0_NOME\r\n       END AS 'NOME',      \r\n       RE5_DESCR AS 'TPDESP',\r\n       RC1_NUMTIT,\r\n       RC1_VALOR,\r\n       RC1_VENCTO,\r\n       A2_NOME,\r\n       A2_CGC,\r\n       A2_BANCO,\r\n       A2_AGENCIA,\r\n       A2_NUMCON,     \r\n       RTRIM(ED_CODIGO) + ' - ' + ED_DESCRIC AS NATUREZA\r\nFROM RC1480 AS RC1\r\n    INNER JOIN RE5010 AS RE5\r\n        ON RE5_TABELA = 'RC1'\r\n           AND RC1_TPDESP = RE5_CODIGO\r\n           AND RE5.D_E_L_E_T_ = ' '\r\n    INNER JOIN RE0480 AS RE0\r\n        ON RE0_FILIAL = RC1_FILTIT\r\n           AND RE0_NUM = RC1_PRONUM\r\n           AND RE0.D_E_L_E_T_ = ' '\r\n    INNER JOIN RD0010 AS RD0\r\n        ON RD0_CODIGO = RE0_RECLAM\r\n           AND RD0.D_E_L_E_T_ = ' '\r\n    INNER JOIN SZ6010 AS SZ6\r\n        ON Z6_TABELA = 'DIR_REGIO'\r\n           AND Z6_ITEM = RE0_XCDDIR\r\n           AND SZ6.D_E_L_E_T_ = ' '\r\n    INNER JOIN SZV010 AS SZV\r\n        ON ZV_REGIONA = RE0_XREGIO\r\n           AND SZV.D_E_L_E_T_ = ' '\r\n    INNER JOIN SA2010 AS SA2\r\n        ON A2_COD = RC1_FORNEC\r\n           AND RC1_LOJA = A2_LOJA\r\n           AND SA2.D_E_L_E_T_ = ' '\r\n    INNER JOIN SZM010 AS SZM\r\n        ON ZM_FILORIG = RE0_FILIAL\r\n           AND SZM.D_E_L_E_T_ = ' '\r\n    INNER JOIN SED010 AS SED\r\n        ON RC1_NATURE = ED_CODIGO\r\n           AND SED.D_E_L_E_T_ = ' '\r\nWHERE RC1_FILTIT = '2B'\r\n      AND RC1_CODTIT = 'APT'\r\n      AND RC1_PREFIX = '2BP'\r\n      AND RC1_NUMTIT = '000009999'\r\n      AND RC1.D_E_L_E_T_ = ' ';\r\n<\/pre>\n<p>Esse <strong>Worktable<\/strong> nos mostra que essa query est\u00e1 utilizando muito tempdb:<\/p>\n<pre class=\"lang:tsql decode:true\">Table 'Worktable'. Scan count 0, logical reads 655602\r\nTable 'RC1480'. Scan count 1, logical reads 6\r\nTable 'SA2010'. Scan count 1, logical reads 23442\r\nTable 'RD0010'. Scan count 1, logical reads 1782<\/pre>\n<p>Olhando o plano de execu\u00e7\u00e3o tamb\u00e9m podemos ver essa informa\u00e7\u00e3o:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-8722 aligncenter\" src=\"https:\/\/www.fabriciolima.net\/blog\/wp-content\/uploads\/2018\/01\/queryprotheysparte7_1.png\" alt=\"\" width=\"740\" height=\"471\" srcset=\"https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/01\/queryprotheysparte7_1.png 737w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/01\/queryprotheysparte7_1-300x191.png 300w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/01\/queryprotheysparte7_1-700x445.png 700w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/01\/queryprotheysparte7_1-410x261.png 410w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/01\/queryprotheysparte7_1-100x64.png 100w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/01\/queryprotheysparte7_1-275x175.png 275w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/01\/queryprotheysparte7_1-20x13.png 20w\" sizes=\"auto, (max-width: 740px) 100vw, 740px\" \/><\/p>\n<p>Quando virem um operador com &#8220;<strong>Spool<\/strong>&#8221; no nome, j\u00e1 visualizem que sua query est\u00e1 armazenando dados no <strong>tempdb<\/strong> para reutilizar esses dados posteriormente nesse plano.<\/p>\n<p>Quando verem uma<strong> seta grande<\/strong>, significa que muito dado est\u00e1 sendo trafegado por ali.<\/p>\n<p>Ou seja, pelo <strong>SET STATISTICS IO<\/strong> eu j\u00e1 tinha visto que o SQL estava usando o tempdb devido a quantidade de reads no <strong>Worktable<\/strong>. Eu abro o plano e vejo um <strong>Spool<\/strong> com uma <strong>seta<\/strong> desse tamanho.<\/p>\n<p>Tenho que tentar ver algo nessa tabela <strong>RD0010<\/strong> que est\u00e1 envolvida nessa bagun\u00e7a toda.<\/p>\n<p>Sem essa an\u00e1lise acima, nosso primeiro pensamento seria ir direto na tabela <strong>RC1480<\/strong> que \u00e9 utilizada pelo <strong>WHERE<\/strong> e criar um \u00edndice pela coluna abaixo:<\/p>\n<pre class=\"lang:tsql decode:true \">AND RC1_NUMTIT = '000009999'<\/pre>\n<p>Contudo, n\u00e3o vou fazer isso. Vamos seguir na linha do tempdb primeiro.<\/p>\n<p>Procurando a tabela <strong>RD0010<\/strong> na query, vemos que um join \u00e9 realizado com ela:<\/p>\n<pre class=\"lang:tsql decode:true\">INNER JOIN RD0010 AS RD0 ON RD0_CODIGO = RE0_RECLAM AND RD0.D_E_L_E_T_ = ' '<\/pre>\n<p>N\u00e3o existe \u00edndice nessa coluna <strong>RD0_CODIGO<\/strong>. Se eu criar, ser\u00e1 que vai ajudar?<\/p>\n<p>Vamos tentar&#8230;<\/p>\n<p>Criando o \u00edndice:<\/p>\n<pre class=\"lang:tsql decode:true \">CREATE NONCLUSTERED INDEX RD0010W01\r\nON [dbo].RD0010 (RD0_CODIGO,D_E_L_E_T_)\r\nINCLUDE (RD0_NOME) with(DATA_COMPRESSION=PAGE,FILLFACTOR=90)<\/pre>\n<p>Rodando a query novamente&#8230;. <strong>WOW!!!!<\/strong><\/p>\n<p>Milagrosamente sumiu aquele n\u00famero gigante de leituras no tempdb:<\/p>\n<pre class=\"lang:tsql decode:true \">Table 'Worktable'. Scan count 0, logical reads 535\r\nTable 'RD0010'. Scan count 1, logical reads 3\r\nTable 'SA2010'. Scan count 1, logical reads 23442\r\nTable 'RC1480'. Scan count 1, logical reads 6<\/pre>\n<p>Muito bom Fabr\u00edcio, mas ainda tem uma tabela fazendo mais <strong>23 mil reads<\/strong> ai, n\u00e3o consegue resolver ela tamb\u00e9m?<\/p>\n<p>Est\u00e1 bem&#8230; Vamos aproveitar a viagem e ver ela tamb\u00e9m .<\/p>\n<p>Seguindo a mesma ideia da tabela anterior, criamos o \u00edndice abaixo pensando no join com essa tabela <strong>SA2010<\/strong>:<\/p>\n<pre class=\"lang:tsql decode:true \">CREATE NONCLUSTERED INDEX SA2010W01\r\nON [dbo].[SA2010] ([A2_COD],[A2_LOJA],[A2_CGC],[D_E_L_E_T_])\r\nINCLUDE ([A2_NOME],[A2_BANCO],[A2_AGENCIA],[A2_NUMCON])\r\nwith(DATA_COMPRESSION=PAGE,FILLFACTOR=90)\r\n<\/pre>\n<p>Rodando a query novamente, agora baixamos para 3 leituras de p\u00e1ginas tamb\u00e9m na SA2:<\/p>\n<pre class=\"lang:tsql decode:true \">Table 'SA2010'. Scan count 1, logical reads 3<\/pre>\n<p>Colocando um waitfor delay na execu\u00e7\u00e3o da query conseguimos visualizar no log de queries demoradas:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-8721 aligncenter\" src=\"https:\/\/www.fabriciolima.net\/blog\/wp-content\/uploads\/2018\/01\/queryprotheysparte7_2-1.png\" alt=\"\" width=\"846\" height=\"257\" srcset=\"https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/01\/queryprotheysparte7_2-1.png 830w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/01\/queryprotheysparte7_2-1-300x91.png 300w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/01\/queryprotheysparte7_2-1-768x233.png 768w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/01\/queryprotheysparte7_2-1-700x213.png 700w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/01\/queryprotheysparte7_2-1-410x124.png 410w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/01\/queryprotheysparte7_2-1-100x30.png 100w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/01\/queryprotheysparte7_2-1-275x83.png 275w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/01\/queryprotheysparte7_2-1-20x6.png 20w\" sizes=\"auto, (max-width: 846px) 100vw, 846px\" \/><\/p>\n<p>Ela rodou em <strong>0,11 segundos<\/strong> e a diferen\u00e7a de leituras de p\u00e1ginas<strong> (691 mil para 2mil)<\/strong> e do consumo de CPU<strong> (2 mil para 100)<\/strong> \u00e9 consider\u00e1vel!!!<\/p>\n<p>\u00c9 isso ai pessoal, melhoramos mais uma query no Protheus.<\/p>\n<p>Com isso, encerramos essa s\u00e9rie de Posts sobre Melhoria de Performance de Consultas Totvs.<\/p>\n<p><strong>A n\u00e3o Fabr\u00edcio!!! S\u00e9rio???<\/strong><\/p>\n<p>S\u00e9rio&#8230;<\/p>\n<p>Espero que tenha contribu\u00eddo de alguma forma no seu aprendizado.<\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #ff0000;\"><strong>Atualizado no dia 07\/10\/2020:<\/strong><\/span><\/p>\n<p>Publiquei um curso com 11 horas de dura\u00e7\u00e3o com toda minha experi\u00eancia de anos no assunto e de dezenas de clientes Protheus atendidos:<\/p>\n<p>Curso:\u00a0<a class=\"external-link wpel-icon-left\" href=\"https:\/\/cursos.powertuning.com.br\/course?courseid=melhorando-a-performance-de-consultas-no-totvs-protheus\" target=\"_blank\" rel=\"nofollow external noopener noreferrer\" data-wpel-link=\"external\">Melhorando a Performance de Consultas no Totvs Protheus<\/a><\/p>\n<p>Gravei uma aula gr\u00e1tis com 60 minutos de dura\u00e7\u00e3o sobre o que voc\u00ea deve aprender para melhorar a performance no Protheus:<\/p>\n<div class=\"fluid-width-video-wrapper\"><a href=\"https:\/\/www.youtube.com\/watch?v=BKmUa3aZn6s\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/www.youtube.com\/watch?v=BKmUa3aZn6s<\/a><\/div>\n<div><\/div>\n<p><b>Gostou desse Post?<\/b><\/p>\n<p>Curta, comente, compartilhe com os coleguinhas\u2026<\/p>\n<p>Assine meu canal no\u00a0<a class=\"external-link wpel-icon-left\" href=\"https:\/\/www.youtube.com\/channel\/UCeBRAO_LLrUdSrOXIywjzRA\" target=\"_blank\" rel=\"external noopener noreferrer nofollow\" data-wpel-link=\"external\">Youtube<\/a>\u00a0e curta minha\u00a0<a class=\"external-link wpel-icon-left\" href=\"https:\/\/www.facebook.com\/FabricioLimaSolucoesemBancodeDados\/\" target=\"_blank\" rel=\"external noopener noreferrer nofollow\" data-wpel-link=\"external\">P\u00e1gina no Facebook<\/a>\u00a0para receber Dicas de Leituras e Eventos sobre SQL Server.<\/p>\n<p>Abra\u00e7os,<\/p>\n<p>Fabr\u00edcio Lima<\/p>\n<p>Microsoft Data Platform MVP<\/p>\n<p>Consultor e Instrutor SQL Server<\/p>\n<p>Trabalha com SQL Server desde 2006<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Fala pessoal, Como tudo que \u00e9 bom dura, pouco, esse \u00e9 o \u00faltimo epis\u00f3dio da nossa s\u00e9rie de artigos de Tuning de consultas no Totvs Protheus. Lembrando que essas dicas valem para queries de outros sistemas tamb\u00e9m. Antes de lerem esse post, caso ainda n\u00e3o tenham lido os anteriores, sugiro que fa\u00e7am para seguirem a [&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":""},"categories":[3,942,991,1248,33,280],"tags":[15,1031,1032,1101,1099,1100,1097,1098,1096,1048,1044,1103,942,1102,1595,1054,23,1029,1030,1088,1089,1025,1026,1049,1045,110,1034,1033,1597,1016,1040,1019,1598,1035,1042,1023,1024,1596,1046,1021,1020,1039,1053,1022,1018,1059,1047,1041,1036,1052,1060,1038,1051,33,1057,1017,1015,1055,1050,1043],"class_list":["post-8718","post","type-post","status-publish","format-standard","hentry","category-administracao-de-bd","category-consultoria-sql-server","category-dba-remoto","category-queries-do-dia-a-dia","category-sql-server","category-virtual-pass-br","tag-banco-de-dados","tag-banco-protheus","tag-banco-totvs","tag-consultor-crm","tag-consultor-datasul","tag-consultor-microsiga","tag-consultor-protheus","tag-consultor-rm","tag-consultor-totvs","tag-consultoria-microsiga","tag-consultoria-protheus","tag-consultoria-rm","tag-consultoria-sql-server","tag-consultoria-totvs","tag-crm-datasul-datasul-erp","tag-datasul-totvs","tag-dba","tag-dba-protheus","tag-dba-totvs","tag-dica-banco-de-dados-protheus","tag-dicas-banco-de-dados-protheus","tag-erp","tag-erp-com-sql-server","tag-erp-microsiga","tag-erp-protheus","tag-indice","tag-lentidao-banco-de-dados","tag-lentidao-protheus","tag-lentidao-protheus-12","tag-microsiga","tag-microsiga-protheus","tag-microsiga-sql-server","tag-migracao-protheus-12","tag-performance-protheus","tag-protheus","tag-protheus-10","tag-protheus-11","tag-protheus-12","tag-protheus-microsiga","tag-protheus-microsoft-sql-server","tag-protheus-sql-server","tag-protheus-totvs","tag-rm-sistemas","tag-rm-sql-server","tag-siga","tag-sistema-crm","tag-sistema-microsiga","tag-sistema-protheus","tag-sistema-rm","tag-sistema-rm-totvs","tag-sistema-wms","tag-sistemas-de-gestao","tag-sistemas-erp","tag-sql-server","tag-suporte-totvs","tag-top-connect","tag-totvs","tag-totvs-datasul","tag-totvs-microsiga","tag-totvs-protheus"],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/posts\/8718","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=8718"}],"version-history":[{"count":10,"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/posts\/8718\/revisions"}],"predecessor-version":[{"id":13839,"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/posts\/8718\/revisions\/13839"}],"wp:attachment":[{"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/media?parent=8718"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/categories?post=8718"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/tags?post=8718"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}