A criação de um banco de dados, ao contrário do que muitos pensam, não é tarefa elementar. Na realidade, o projeto de um banco de dados não termina com a definição das tabelas, campos, relacionamentos e índices. Isto resolve o lado lógico da implementação. Mas não diz nada sobre a questão física, ou seja, como o banco de dados vai usar discos e memória para obter máxima performance.
No DB2 LUW (para Linux, Unix e Windows), caso o DBA não tome nenhuma providência, todas as tabelas e seus índices serão criados usando o mesmo tablespace (USERSPACE1), que usa containers (área alocada no disco) gerenciados pelo DB2 e o bufferpool default para gerenciamento da memória da máquina (IBMDEFAULTBP). Caso você não esteja familiarizado com detalhes da estrutura de dados do DB2, consulte o tópico “Referências” no fim deste artigo.
Isso quer dizer que os dados de todas as tabelas, bem como as páginas de índice sobre estes dados, usarão a mesma área alocada em disco e acessarão a mesma porção de memória alocada.
Se lembrarmos que bancos de dados otimizados aproveitam-se de paralelismo no uso dos recursos de hardware para obter melhor performance, fica evidente que esta configuração default do DB2 LUW não é solução adequada para grandes bases de dados.
É tarefa do DBA definir a estratégia de uso dos tablespaces de modo a maximizar o paralelismo e possibilitar um bom desempenho em um banco de dados.
Quando trabalho com o DB2, eu costumo observar algumas recomendações genéricas sobre uso de tablespaces, containers e bufferpools, que eu listo a seguir:
- Sempre que possível, usar tablespaces do tipo “automatic storage”, que é default das versões 9.7 e posteriores. Assim a definição dos tipos de containers é feita pelo próprio DB2;
- Cada tablespace deve usar um bufferpool de tamanho adequado ao tamanho dos registros que ele irá comportar, ou seja, 4k, 8k, 16k ou 32k. Nunca usar tamanhos maiores que os necessários;
- Usar um tablespace para cada tabela não particionada que existir no banco, a fim de permitir o paralelismo citado anteriormente;
- Usar um tablespace separado para os índices de cada tabela;
- Tabelas particionadas devem usar um tablespace por partição;
- Preferencialmente, os vários tablespaces criados devem usar adequadamente os diversos discos disponíveis no servidor, através da criação de “database partition groups” adequados;
- Tablespaces não precisam necessariamente ter bufferpools exclusivos, mas deve haver bom senso na escolha de quais tablespaces vão compartilhar o mesmo bufferpool;
- No caso de tabelas que costumam operar em conjunto (JOINs), definir tablespaces que usem bufferpools diferentes, de tal modo que mais dados possam ser preservados em cada buffer de memória durante a operação de junção.
Estas recomendações costumam ser úteis, mas deve-se lembrar que cada implementação requer suas próprias considerações. Otimização de bancos de dados é um tópico que envolve muitos fatores e, como costumo dizer, não existe bala de prata que possa ser aplicada a todos os casos.
Por hoje é só. Até a próxima!
Referências
- Crivelini, Wagner. DBA 101: administrando estruturas de dados do DB2. IBM DEVELOPERWORKS. 02/Nov/2012.
- Patel, Ani. DB2 Basics: Table spaces and buffer pools. IBM DEVELOPERWORKS. 22/Abr/2010.
- IBM. Comparison of SMS, DMS and automatic storage table spaces. IBM DB2 LUW V9.7 INFOCENTER. 27/Mar/2013.