15 pontos por GN⁺ 2024-07-28 | 4 comentários | Compartilhar no WhatsApp
  • O SQLite pode ler e gravar pequenos BLOBs (por exemplo, imagens em miniatura) 35% mais rápido do que ler ou gravar arquivos individuais com fread() ou fwrite()
  • Além disso, um único banco de dados SQLite que armazena BLOBs de 10 KB usa cerca de 20% menos espaço em disco do que armazenar os BLOBs como arquivos individuais
  • A diferença de desempenho parece ocorrer porque, ao trabalhar com um banco de dados SQLite, as chamadas de sistema open() e close() são feitas apenas uma vez, enquanto ao usar BLOBs em arquivos individuais, open() e close() são chamados uma vez para cada BLOB. O overhead de open() e close() parece ser maior do que o overhead de usar o banco de dados
  • A redução de tamanho acontece porque arquivos individuais são preenchidos até o próximo múltiplo do tamanho do bloco do sistema de arquivos, enquanto os BLOBs são empacotados de forma mais densa no banco de dados SQLite

Observações

  • O número de 35% é aproximado. Os tempos reais variam conforme o hardware, o sistema operacional e os detalhes do experimento, e há variação aleatória de desempenho no hardware real
  • O número de 35% vem da execução dos testes em todos os sistemas aos quais o autor tinha acesso fácil. Alguns revisores relataram que, em seus sistemas, o SQLite apresentou latência maior do que I/O direto. Essa diferença ainda não foi compreendida
  • O SQLite não teve desempenho tão bom quanto o I/O direto quando os experimentos foram executados com cache frio do sistema de arquivos
  • Este documento contesta a suposição comum de que um banco de dados relacional deveria ser mais lento do que I/O direto no sistema de arquivos
  • Segundo um estudo de 2022, em cargas de trabalho reais, o SQLite foi aproximadamente 2 vezes mais rápido do que Btrfs e Ext4 no Linux

Como foi medido

  • O desempenho de I/O foi medido usando o programa kvtest.c da árvore de código-fonte do SQLite
  • Para compilar esse programa de teste, reúna o arquivo-fonte kvtest.c em um diretório junto com os arquivos-fonte amalgamados do SQLite sqlite3.c e sqlite3.h, e então execute em Unix um comando semelhante ao seguinte
  • O programa kvtest gerado por esse comando é usado para criar um banco de dados de teste composto por 100.000 BLOBs aleatórios não comprimidos, cada um com tamanho entre 8.000 e 12.000 bytes
  • Para criar cópias de todos os BLOBs como arquivos individuais em um diretório, pode-se executar o comando export usando a opção de linha de comando --tree
  • Os comandos a seguir são usados para medir o desempenho de leitura dos BLOBs no banco de dados e de leitura dos BLOBs em arquivos individuais
  • Com a opção --blob-api, o SQLite pode carregar o conteúdo do BLOB usando a função sqlite3_blob_read() em vez de executar instruções SQL, ficando um pouco mais rápido no teste de leitura

Medição de desempenho de leitura

  • No Windows 10, é possível ler conteúdo do banco de dados SQLite cerca de 5 vezes mais rápido do que ler diretamente do disco
  • No Android, o SQLite é cerca de 35% mais rápido do que ler do disco
  • Ao ler de um banco de dados mapeado em memória usando sqlite3_blob_read(), no Mac e no Android ele é 2 vezes mais rápido do que ler arquivos individuais do disco, e no Windows é 10 vezes mais rápido

Medição de desempenho de gravação

  • Em todos os sistemas, tanto no I/O direto quanto no SQLite, o desempenho de gravação é de 5 a 15 vezes mais lento do que o de leitura
  • Nos testes de gravação, softwares antivírus quase não afetam as gravações no SQLite, mas gravar diretamente no disco fica cerca de 10 vezes mais lento
  • Isso provavelmente ocorre porque o SQLite altera apenas um único arquivo de banco de dados, enquanto gravar diretamente no disco altera milhares de arquivos individuais que precisam ser verificados pelo antivírus

Resultados gerais

  • O SQLite é competitivo com BLOBs armazenados em arquivos separados no disco, tanto em leitura quanto em gravação, e normalmente é mais rápido
  • O SQLite é muito mais rápido do que gravar diretamente no disco no Windows quando a proteção antivírus está ativada
  • Leitura é cerca de 10 vezes mais rápida do que gravação em todos os sistemas, tanto no SQLite quanto no I/O direto em disco
  • O desempenho de I/O varia muito conforme o sistema operacional e o hardware. É necessário medir no seu próprio ambiente antes de tirar conclusões
  • Alguns outros mecanismos de banco de dados SQL recomendam aos desenvolvedores armazenar BLOBs em arquivos separados e salvar apenas o nome do arquivo no banco de dados. Nesse caso, armazenar o BLOB inteiro no banco de dados oferece desempenho de leitura e gravação muito superior no SQLite

Opinião do GN⁺

  • É muito interessante que o desempenho do SQLite seja melhor do que o de ler e gravar arquivos individuais. Isso parece poder ajudar a melhorar o desempenho de aplicações que usam banco de dados
  • No entanto, esses resultados de benchmark não se aplicam necessariamente de forma geral a todas as situações. Eles podem variar conforme as características dos dados, o padrão de acesso e a configuração de hardware. Para aplicações importantes, é essencial fazer benchmarks com a carga de trabalho real
  • Além disso, o SQLite tem a vantagem de poder evitar verificações de antivírus. Isso deve ser especialmente útil em aplicações que lidam com grandes quantidades de arquivos pequenos
  • A desvantagem do SQLite é que todos os dados ficam armazenados em um único arquivo, então, se o arquivo do banco de dados for corrompido, todos os dados podem ser perdidos. Por isso, é importante fazer backup regular do arquivo do banco de dados

4 comentários

 
iolothebard 2024-07-28

Talvez fosse preciso incluir no banco de dados até o acesso aos atributos do arquivo (nome do arquivo, tamanho, permissões de acesso, …),
ou então comparar com E/S em bloco, e não com E/S de arquivo…
De um jeito ou de outro, o SQLite realmente é rápido.

 
GN⁺ 2024-07-28
Comentários no Hacker News
  • Como não há atributos nem metadados de sistema de arquivos, não é necessário gravar ou atualizar atributos extras, nem verificar arquivos físicos, pipes/links simbólicos, permissões ou incompatibilidades de alinhamento de tamanho de bloco, então basta um único comando de abertura

    • Faz sentido quando se abre mão de funcionalidades e se ignora o design de propósito geral
    • Se você usar um mapeamento FUSE para SQLite e montar um diretório para acesso, o desempenho pode ser parecido ou até pior
    • Se desativar atributos e criar um sistema de arquivos customizado com tamanho de bloco otimizado, é possível obter desempenho semelhante
    • Há a simplicidade de poder explorar e manipular arquivos com comandos de shell como rsync
    • SQLite é adequado para ativos estáticos empacotados ou aplicações do tipo appliance
  • O aumento de velocidade de 4x no Windows 10 destaca o quão lentas são as chamadas ao sistema de arquivos do Windows

  • Surgiu a ideia de registrar em tempo real todas as notas produzidas por um piano digital

    • Usando SQLite, tudo foi salvo em uma única tabela em que cada linha é um evento MIDI do piano
    • O desempenho é bom e depois dá para analisar os dados
  • Foi interessante comparar isso com pesquisas de SO em um laboratório de bancos de dados

    • Bancos de dados relacionais são otimizados para registros individuais pequenos e consistência
    • Conforme o tamanho das linhas aumenta, o desempenho cai drasticamente
  • Considerando adicionar ao banco SQLite no modo WAL2

    • Quase não há penalidade de desempenho de escrita, e há grandes vantagens para leitura/análise
  • Em um banco SQLite, as chamadas de sistema open() e close() são feitas apenas uma vez

    • Há menos sobrecarga do que usar blobs em arquivos individuais
  • Não é recomendado armazenar arquivos usando campos blob no SQLite

    • O tamanho máximo de um blob é 2 GB
    • É preciso serializar/desserializar objetos em bytes
    • Para interagir com outros sistemas/serviços, arquivos são necessários
    • SQLite tem configurações para lidar com requisições paralelas, mas o banco acaba bloqueado por causa de requisições concorrentes
  • O fato de algo construído sobre um sistema de arquivos ser mais rápido do que o próprio sistema de arquivos significa que o sistema de arquivos fica lento quando é usado de maneira não otimizada

  • Excluir muitas linhas em um banco SQLite é mais lento do que excluir arquivos

  • Todo acesso a sistemas de arquivos/unidades é gerenciado pelo SO

    • O arquivo do banco é armazenado em clusters no disco
    • Um sistema gerenciador de banco de dados é criado por conveniência para resolver domínios e problemas específicos
 
halfenif 2024-07-28

Há 20 anos, usei bem uma arquitetura de colocar arquivos como blobs no Oracle DB... mas toda vez eu precisava explicar às pessoas as vantagens disso. Claro que nem sempre era bem-sucedido.

 
narusas 2024-07-29

Há 20 anos, o preço dos discos SAN da Oracle provavelmente não era nada barato...