Descobri isso recentemente e eu não fazia ideia.
Estava conversando algumas semanas atrás com meu amigo Wallace Freitas (LinkedIn), e ele havia me falado que o DbSeek e MsSeek haviam diferenças, sendo que o segundo era mais performático.
Eu confesso que não sabia dessa informação e fui pesquisar, até que encontrei o link no TDN que fala sobre isso – https://tdn.totvs.com/display/framework/Desempenho+DbSeek+x+MsSeek
Baseado no exemplo do TDN, eu montei o exemplo abaixo:
#Include "TOTVS.ch" Static nVezes := 10000 /*/{Protheus.doc} User Function zSeek Funcao para comparar desempenho entre DbSeek e MSSeek @type Function @author Atilio @since 27/06/2020 @version version @example u_zSeek() @see https://tdn.totvs.com/display/framework/Desempenho+DbSeek+x+MsSeek /*/ User Function zSeek() Local aArea := GetArea() //Teste com DbSeek fTestDB() //Teste com MsSeek fTestMS() RestArea(aArea) Return Static Function fTestDB() Local nAtual Local cHoraIni := Time() Local cHoraFin Local cDifer //Abrindo a tabela de Clientes e posicionando no topo DbSelectArea("SA1") SA1->(DbSetOrder(1)) SA1->(DbGoTop()) //Percorre o número de vezes e atualiza a hora final ao sair do laco For nAtual := 1 To nVezes SA1->(DbSeek(FWxFilial("SA1") + "000001" + "01" )) Next cHoraFin := Time() //Mostra mensagem ao usuario cDifer := ElapTime(cHoraIni, cHoraFin) MsgInfo("DbSeek:" + CRLF + "Hora Inicio: " + cHoraIni + CRLF + "Hora Final: " + cHoraFin + CRLF + "Total: " + cDifer, "Atencao") Return Static Function fTestMS() Local nAtual Local cHoraIni := Time() Local cHoraFin Local cDifer //Abrindo a tabela de Clientes e posicionando no topo DbSelectArea("SA1") SA1->(DbSetOrder(1)) SA1->(DbGoTop()) //Percorre o número de vezes e atualiza a hora final ao sair do laco For nAtual := 1 To nVezes SA1->(MsSeek(FWxFilial("SA1") + "000001" + "01" )) Next cHoraFin := Time() //Mostra mensagem ao usuario cDifer := ElapTime(cHoraIni, cHoraFin) MsgInfo("MsSeek:" + CRLF + "Hora Inicio: " + cHoraIni + CRLF + "Hora Final: " + cHoraFin + CRLF + "Total: " + cDifer, "Atencao") Return
E realmente o MsSeek é mais rápido que o DbSeek. Fazendo a mesma operação 10.000 vezes (de procurar um registro na SA1), o MsSeek demorou 4 segundos (média de 250 seeks por segundo), enquanto o DbSeek demorou 16 segundos (média de 62,5 seeks por segundo). Confira o print abaixo de resultado (a esquerda DbSeek e a direita MsSeek).
Bom pessoal, por hoje é só.
Abraços e até a próxima.
Dica importantíssima, principalmente quando tem que dar uma melhorada na performance daquela rotina que você vê, e a principio não tem muita coisa a se fazer.
Opa, obrigado pelo feedback Sulivan, realmente é algo bem interessante.
Grande abraço jovem.
muito boa a dica, um camarada da TOTVS havia me falado isso também….
Opa, obrigado pelo comentário Patini, eu realmente desconhecia.
Grande abraço.
Fala Daniel beleza?
Cara é um prazer poder estar contribuindo com o T.I.
Como sempre seus artigos bem detalhados e explicativos.
Excelente trabalho.
Abraços
Fala Wallace, bem e você?
Opa, obrigado pelo comentário e pela contribuição jovem.
Grande abraço.
Deve ter algum cuidado ao usar o MsSeek? Ele é indicado para quando procura só um mesmo registro varias vezes ou quando trocamos de registro também? Obrigado pelo seu conteúdo.
Eu que agradeço pelo comentário.
Respondendo a dúvida, o cuidado são os mesmos do DbSeek, como por exemplo, usar a referência antes.
No contexto explicado no link do TDN e no exemplo demonstrado no artigo, são quando o mesmo registro é processado várias vezes, ideal para rotinas que trabalhem com contabilidade ou estrutura de produtos onde pode ter inúmeros posicionamentos em vários ou no mesmo registro.
O ideal mesmo, é se possível fazer uma query para manipular os dados, mas entre o DbSeek e o MsSeek, o segundo é mais performático por buscar os dados em memória, caso o registro já tenha sido posicionado anteriormente.
Show, hein…
Bora alterar 4376 ocorrências do dbseek.
Grande Pedroso, rapaz, tudo isso de ocorrência? rsrs… Aqui no projeto deu 2893, bastantinho também né rs… Grande abraço jovem.
Bom dia Daniel, tudo bem?
Muito interessante a dinâmica de explicação e uma dica muito valiosa.
Só queria tirar uma duvida, devo tomar algum cuidado ao preferir utilizar o MSseek do que o DbSeek, por exemplo, caso na tabela não esteja posicionado no registro ou algo assim?
Agradeço desde já a atenção!
Boa tarde Henrique, tudo joia graças a Deus e você?
Opa, obrigado pelo feedback.
Recentemente teve uma dúvida parecida no nosso grupo do WhatsApp, segue trecho da resposta que enviamos na ocasião:
[…]
Quanto ao MsSeek x DbSeek, no TDN não tem informações complementares sobre cuidados ao utilizar um ou outro.
Ai por boas práticas, não se esqueça de utilizar GetArea com RestArea, usar referência do alias e nunca utilizar Trim em Seek, conforme nossas aulas 11 e 12 do curso de Boas Práticas em AdvPL ( https://terminaldeinformacao.com/2021/05/28/curso-boas-praticas-de-programacao-em-advpl/ )
Como leitura complementar, veja sobre:
+ Importância do GetArea e RestArea: https://terminaldeinformacao.com/2022/07/20/a-importancia-do-getarea-e-restarea/
+ Por qual motivo NUNCA devemos usar Trim em Seeks: https://terminaldeinformacao.com/2023/10/06/por-qual-motivo-nunca-devemos-usar-trim-em-seeks/
[…]
Um grande abraço.
Boa tarde Daniel, tudo joia?
Excelente trabalho que você tem feito compartilhando seus conhecimentos.
Em relação as MsSeek ele mantém em memória os dados isso não pode causar mais consumo de memoria em relação ao DbSeek?
Agradeço desde já a atenção!
Bom dia Luccas, tudo joia graças a Deus e você?
Opa, primeiramente obrigado pelo feedback, é muita bondade e generosidade sua.
Agora quanto a utilização do MsSeek ou do DbSeek, nos clientes que atendo, eu me faço algumas perguntas como:
a. Essa função vai ficar um bom tempo em memória? (tipo vai ser uma outras ações numa tela padrão, ou uma dialog customizada)
b. Ou ela vai ser uma rotina com início, meio e fim como um processamento ou relatório colocada direto no menu?
c. Os usuários utilizam o SIGAADV ou o SIGAMDI? (o segundo cada aba é uma thread, então ao fechar uma, a memória em teoria é liberada)
d. A estrutura do servidor do cliente na aplicação (AppServer) como é de Memória RAM? E a estrutura do banco de dados como é de processamento e leitura de disco?
e. Quantos dados serão processados em estimativa atual e para os próximos meses?
Ai dependendo das respostas acima eu escolho entre usar o DbSeek ou MsSeek, pois por exemplo, mesmo que o MsSeek mantenha mais memória numa thread, assim que a thread encerrar já libera. Agora imagina que a estrutura do cliente onde ta o banco de dados, não tem SSD ou não tem um processamento legal, imagina ficar dando vários DbSeek para encontrar os dados, como que fica o IO de disco.
Então, tudo depende do cenário em que você vai atender, mas cabe sempre antes alinhar com o cliente explicando os prós e contras de ambos, pois pode ser que mesmo que você queira desenvolver usando por exemplo DbSeek, ai o cliente te fala que estão migrando para o cloud ou comprando mais equipamento para ter mais memória RAM e que você pode usar o MsSeek para não ter muito IO no SQL.
Tenha uma ótima e abençoada quarta feira.
Um grande abraço.