[Delphi] Dicas para agilizar o desempenho em uma DBGrid

Olá, pessoal!
Depois que publiquei os artigos sobre dicas do componente DBGrid e sobre a crueldade de um software lento, recebi algumas perguntas de leitores sobre como melhorar o desempenho de consultas e exibição de dados. O artigo de hoje é uma sugestão dor Artur, um destes leitores, que deixou um comentário recente relacionado a esse assunto. Confira!

A lentidão ao carregar dados em um componente TDBGrid pode ser causada por vários fatores que, muitas vezes, nos passam despercebidos. As seis orientações abaixo podem ser úteis para agilizar o carregamento de dados ou, talvez, para evitar futuras lentidões.

1) Revise a instrução Select que consulta os dados

Assim como mencionei no artigo sobre práticas de otimização em banco de dados, as consultas SQL devem trazer apenas os dados que são necessários na visão da DBGrid. Por exemplo, se existem 10 colunas em uma tabela e somente 4 são exibidas em uma DBGrid, as outras 6 podem (e devem) ser retiradas da consulta. Para isso, substitua o asterisco pelas colunas requisitadas, conforme a comparação abaixo:

Além disso, em alguns casos, há tabelas com colunas do tipo BLOB, que armazenam dados binários de arquivos ou textos longos. Se essas colunas forem adicionadas na consulta, o tempo de retorno será ainda mais demorado. A minha recomendação é trazer estes dados sob demanda em uma instrução separada, como comentei no artigo sobre eventos de tela.

2) Evite abrir e fechar o DataSet repetidas vezes

Quando for necessário aplicar um filtro nos dados, como um intervalo de datas, procure utilizar as propriedades Filter e Filtered, ao invés de comandos que fazem acesso ao banco, como CommandText, Close/Open e ExecSQL. A explicação é que a propriedade Filter trabalha com dados em memória, isto é, que já foram carregados.

Entrando mais em detalhes técnicos, o ideal é substituir esses tipos de consulta:

Por filtros como esse:

3) Atente-se aos eventos do DataSet, dos Fields e de pintura da DBGrid

Por falar em eventos de tela, o desenvolvedor também deve ser prudente ao utilizá-los, já que podem impactar no tempo de carregamento dos dados. Por exemplo, você sabia que o evento OnDrawColumnCell do componente DBGrid é chamado para cada registro que é carregado? Insira um ShowMessage neste evento, abra o DataSet e observe a quantidade de vezes que a mensagem é exibida. Logo, se houver um processamento neste evento, é evidente que os dados levarão um tempo maior para serem carregados.

A mesma orientação é válida para eventos do DataSet conectado à DBGrid, como BeforeOpen, AfterOpen, BeforeGetRecords e AfterGetRecords. Embora sejam executados apenas uma vez ao consultar os dados, podem apresentar lentidões se os processamentos forem extensos.

Seguindo a mesma lógica, o evento OnGetText do TField (campo da tabela), como trata a exibição dos dados de uma coluna, também é executado para cada registro e deve ser observado.

4) Adicione filtros na tela para evitar a consulta de vários registros

Muitos desenvolvedores costumam executar a consulta de dados logo quando a tela é aberta. Isso significa que, se houverem 10 mil registros, todos eles serão consultados de uma vez só. Bom, nem preciso comentar que isso é uma falha de desempenho, não é?

Além da demora, esse procedimento também não deixa de ser uma questão de usabilidade. Muitas vezes, o usuário entra na tela para visualizar os dados de apenas 1 registro, e precisa esperar, desnecessariamente, a consulta de todos os registros da tabela.

A recomendação é disponibilizar filtros na tela (como código, descrição, tipo, período, etc…), e realizar a consulta somente quando estes filtros forem informados. Com essa alteração, já consigo apontar 3 vantagens: 1) não haverá “gargalos” ao abrir a tela; 2) o usuário visualiza somente o(s) registro(s) desejado(s); 3) reduz o tráfego de dados em um ambiente cliente/servidor.

5) Ative a paginação de registros com a propriedade PacketRecords

Quem disse que não dá para fazer paginação com Delphi? A propriedade PacketRecords do DataSet permite definir a quantidade de registros que serão “paginados”, ou carregados por vez.

Faça um teste: preencha a propriedade PacketRecords com o valor “100” e abra um DataSet que tenha aproximadamente 1000 registros. Observe que apenas 100 registros serão exibidos inicialmente na DBGrid, porém, ao navegar até a última linha, os próximos 100 registros da tabela serão carregados e exibidos automaticamente.

Este recurso pode ser bastante útil quando a tela exige a consulta de milhares de registros, por uma questão técnica ou por solicitação do cliente, ou mesmo quando a terceira dica, sobre filtros na tela, é inviável.

6) Modere na utilização de componentes de terceiros

Às vezes precisamos de algum comportamento adicional, não existente no componente TDBGrid nativo do Delphi. Como solução, muitos desenvolvedores instalam componentes de terceiros para atender a necessidade. No entanto, vale ressaltar que estes componentes trazem vários outros comportamentos que, em sua maior parte, podem não interessar no momento. Por exemplo, suponha que um componente de terceiro monte toda uma estrutura de agrupamento dinâmico, ative campos Lookup ou faça uma indexação do conteúdo para buscas, quando, o que realmente precisamos, é só um totalizador de valores no rodapé. Por estarem acoplados ao componente, estes outros comportamentos “paralelos” também podem impactar indiretamente na exibição dos dados.

A minha sugestão é criar um novo componente herdado da classe TDBGrid e adicionar os comportamentos desejados, mesmo que exija um pouco mais de tempo. Além de dispensar a instalação de componentes de terceiros, o desenvolvedor ganha a liberdade de customizar o componente de acordo com suas próprias necessidades.

 

Espero que o artigo seja útil, pessoal!
Grande abraço!


André Celestino