Trabalhamos com DB2 LUW (especificamente estamos atualmente em 9.7 FP4) rodando em AIX.
De acordo com as melhores práticas da IBM, eles recomendam que, ao criar uma tabela, você coloque os dados, os índices e os dados LOBs/LONG cada um em seu próprio espaço de tabela. (A razão é melhor controle sobre o disco, manutenção, backups, etc.)
Tablespaces devem ser associados a bufferpools. No momento, a maioria de nossas tabelas e índices cabem em bufferpools e tablespaces de 4K.
Normalmente, com nossos scripts, configuramos um bufferpool 4K BP4K. Em seguida, configuramos pelo menos dois tablespaces de 4K (já que não temos muitos LOBs): TS_DAT_4K para dados e TS_IND_4K para índices. Por padrão, acabamos de atribuir esses espaços de tabela ao bufferpool BP4K.
O que eu me pergunto: como os índices estão em seu próprio espaço de tabela, eles também devem receber seu próprio bufferpool?
Minha razão para pensar isso é baseada na otimização. Se os índices tiverem seu próprio pool de buffers, é mais provável que eles permaneçam na memória (em vez de serem empurrados para fora da memória devido à leitura dos registros da tabela). Isso permitiria uma varredura mais rápida de índices para localizar os registros nas tabelas. E como os índices não compartilhariam mais o mesmo bufferpool com as tabelas, mais tabelas podem agora permanecer na memória para recuperação lógica em vez de uma leitura física. Então, meu pensamento é que isso reduziria a E/S física e, assim, ajudaria no desempenho/manutenção do banco de dados.
Também não posso deixar de me perguntar se isso é apenas pré-otimização, o que é 99% das vezes uma coisa ruim de se fazer, introduzindo sobrecarga extra etc. (especialmente porque não identificamos que precisamos de bufferpools separados ainda com base no desempenho atual. É claro que o aplicativo em desenvolvimento ainda não está em produção e ainda precisa de ajuste do banco de dados....)
Pensamentos sobre isso? Esta é uma prática recomendada? ou apenas pré-otimização e pensamento excessivo?
Permite executar dois bancos de dados hipotéticos (
H1
eH2
) em paralelo, com a mesma quantidade total de RAM para bufferpools (R
).H1
ter um único bufferpool de tamanhoR
.H2
ter dois bufferpools: um de tamanhoI
para páginas de índice, o outro de tamanhoD
para páginas de dados. (ED+I==R
claro.)A questão é:
I
eD
para obterH2
um desempenho melhor do queH1
?Minha resposta é que você não pode em geral. O mecanismo de banco de dados para
H1
tem mais espaço para otimizar seu cache do queH2
. Se houver horas do dia em que mais páginas de índice levariam a um melhor desempenho, ele pode descartar páginas de dados não utilizadas e ter um cache de "principalmente páginas de índice". Se, posteriormente, as páginas de dados ficarem mais quentes, elas poderão remover mais páginas de índice e ter um cache de "principalmente páginas de dados".H2
não posso fazer isso. Depois de terI
páginas de índice armazenadas em cache, ele não pode armazenar mais em cache, mesmo que isso seja o melhor no momento. Está preso lá com um uso abaixo do ideal de RAM.A única maneira de
H2
executar tão bem quantoH1
é se aD
/I
divisão inicialmente escolhida for ideal e a carga de trabalho for muito estável. Isso com certeza pode acontecer, mas aposto que não é um cenário de banco de dados muito comum. Se não for o seu caso, penseH1
como sendo o mesmo,H2
mas com particionamento dinâmico do cache entre dados e páginas de índice gerenciadas diretamente por quem mais sabe como precisa otimizar o I/O (ou seja, o mecanismo de banco de dados).Isso não quer dizer que manter bufferpools diferentes nunca seja uma boa ideia.
Um cenário para isolar páginas específicas em um cache específico que encontrei é ter um "relatório" crítico que precisava ser executado rapidamente (obviamente) o tempo todo e usava algumas tabelas que praticamente nunca foram usadas em outro lugar. Portanto, essas páginas continuaram sendo despejadas e esse "relatório" tinha tempos de execução que variavam muito de execução para execução. Mover um conjunto específico de tabelas (e seus índices) para um pool específico removeu muito da parte de desempenho "não determinística".
Mas isso é abaixo do ideal para o banco de dados como um todo, mais um kudge e mais próximo da otimização Voodoo IMO. (E isso não estava no DB2, mas acredito que seja irrelevante aqui.)
Portanto, meu conselho é: se você tiver X Gb de RAM disponível para cache, use um único buffer, coloque tudo nele e deixe o mecanismo de banco de dados fazer sua mágica lá.
Se você se deparar com um caso de canto que parece se beneficiar da segregação de cache, experimente, faça um benchmark, pense na sobrecarga de ter que manter os números mágicos para cada tamanho de cache e ajuste as consultas, o esquema ou o layout do disco. :)