Eu sei que o sqlite não funciona bem com arquivos de banco de dados extremamente grandes, mesmo quando eles são suportados (costumava haver um comentário no site do sqlite informando que, se você precisar de tamanhos de arquivo acima de 1 GB, poderá considerar o uso de rdbms corporativos. não encontrar mais, pode estar relacionado a uma versão mais antiga do sqlite).
No entanto, para meus propósitos, gostaria de ter uma idéia de quão ruim é realmente antes de considerar outras soluções.
Estou falando de arquivos de dados sqlite na faixa de vários gigabytes, de 2 GB em diante. Alguém tem alguma experiência com isso? Alguma dica / idéia?
database
performance
sqlite
Snazzer
fonte
fonte
Respostas:
Então fiz alguns testes com o sqlite para arquivos muito grandes e cheguei a algumas conclusões (pelo menos para minha aplicação específica).
Os testes envolvem um único arquivo sqlite com uma única tabela ou várias tabelas. Cada tabela tinha cerca de 8 colunas, quase todos os números inteiros e 4 índices.
A idéia era inserir dados suficientes até que os arquivos sqlite tivessem cerca de 50 GB.
Mesa Única
Tentei inserir várias linhas em um arquivo sqlite com apenas uma tabela. Quando o arquivo tinha cerca de 7 GB (desculpe, não posso ser específico sobre a contagem de linhas), as inserções estavam demorando muito. Eu havia estimado que meu teste para inserir todos os meus dados levaria 24 horas ou mais, mas não foi concluído mesmo após 48 horas.
Isso me leva a concluir que uma única tabela sqlite muito grande terá problemas com inserções e provavelmente outras operações também.
Acho que isso não é surpresa, pois a tabela fica maior, a inserção e a atualização de todos os índices levam mais tempo.
Tabelas Múltiplas
Tentei dividir os dados por tempo em várias tabelas, uma tabela por dia. Os dados da tabela 1 original foram divididos em ~ 700 tabelas.
Essa configuração não teve problemas com a inserção, não demorou mais com o passar do tempo, pois uma nova tabela era criada para todos os dias.
Questões de vácuo
Conforme apontado por i_like_caffeine, o comando VACUUM é um problema, quanto maior o arquivo sqlite. À medida que mais inserções / exclusões são feitas, a fragmentação do arquivo no disco fica pior, portanto, o objetivo é periodicamente VACUUM para otimizar o arquivo e recuperar o espaço no arquivo.
No entanto, como indicado na documentação , é feita uma cópia completa do banco de dados para fazer um vácuo, levando muito tempo para ser concluída. Portanto, quanto menor o banco de dados, mais rápida será a conclusão dessa operação.
Conclusões
Para meu aplicativo específico, provavelmente estarei dividindo dados em vários arquivos db, um por dia, para obter o melhor desempenho de vácuo e velocidade de inserção / exclusão.
Isso complica as consultas, mas, para mim, é uma compensação valiosa poder indexar tantos dados. Uma vantagem adicional é que eu posso excluir um arquivo db inteiro para descartar os dados de um dia (uma operação comum para o meu aplicativo).
Eu provavelmente teria que monitorar o tamanho da tabela por arquivo também para ver quando a velocidade se tornará um problema.
É uma pena que não pareça haver um método de vácuo incremental que não seja o vácuo automático . Não posso usá-lo porque meu objetivo para o vácuo é desfragmentar o arquivo (o espaço no arquivo não é grande coisa), o que o vácuo automático não faz. De fato, a documentação afirma que isso pode piorar a fragmentação, por isso tenho que recorrer periodicamente a um vácuo total no arquivo.
fonte
Estamos usando DBS de mais de 50 GB em nossa plataforma. não reclama funciona muito bem. Verifique se você está fazendo tudo certo! Você está usando instruções predefinidas? * SQLITE 3.7.3
Aplique essas configurações (logo após criar o banco de dados)
Espero que isso ajude os outros, funciona muito bem aqui
fonte
PRAGMA main.temp_store = MEMORY;
.Criei bancos de dados SQLite com tamanho de até 3,5 GB sem problemas visíveis de desempenho. Se bem me lembro, acho que o SQLite2 pode ter alguns limites mais baixos, mas não acho que o SQLite3 tenha esses problemas.
De acordo com a página Limites do SQLite , o tamanho máximo de cada página do banco de dados é 32K. E o máximo de páginas em um banco de dados é 1024 ^ 3. Então, pela minha matemática, chega a 32 terabytes como o tamanho máximo. Eu acho que você atingirá os limites do seu sistema de arquivos antes de atingir o SQLite!
fonte
Muito do motivo que levou mais de 48 horas para fazer suas inserções é por causa de seus índices. É incrivelmente mais rápido:
1 - Solte todos os índices 2 - Faça todas as inserções 3 - Crie índices novamente
fonte
Além da recomendação usual:
Aprendi o seguinte com minha experiência com o SQLite3:
Altere a tabela posteriormente, conforme necessárioVocê não pode adicionar restrições com ALTER TABLE).Pergunta / comentário bem-vindo. ;-)
fonte
Eu acho que as principais reclamações sobre o dimensionamento do sqlite são:
fonte
Eu tenho um banco de dados SQLite de 7 GB. Para executar uma consulta específica com uma junção interna, são necessários 2,6s. Para acelerar isso, tentei adicionar índices. Dependendo de quais índices eu adicionei, algumas vezes a consulta caiu para 0,1s e outras vezes subiu para 7s. Acho que o problema no meu caso foi que, se uma coluna é altamente duplicada, a adição de um índice prejudica o desempenho :(
fonte
Costumava haver uma declaração na documentação do SQLite de que o limite prático de tamanho de um arquivo de banco de dados era de algumas dezenas de GB: s. Isso ocorreu principalmente devido à necessidade do SQLite "alocar um bitmap de páginas sujas" sempre que você iniciou uma transação. Assim, 256 bytes de RAM foram necessários para cada MB no banco de dados. A inserção em um arquivo DB de 50 GB exigiria um alto (2 ^ 8) * (2 ^ 10) = 2 ^ 18 = 256 MB de RAM.
Mas, como nas versões recentes do SQLite, isso não é mais necessário. Leia mais aqui .
fonte
2^18
é na verdade apenas 256 K.Eu tive problemas com grandes arquivos sqlite ao usar o comando vacuum.
Ainda não testei o recurso auto_vacuum. Se você espera atualizar e excluir dados com frequência, vale a pena examinar.
fonte