A primeira versão do meu repositório de análise de ações executava as análises em um motor OLTP, e a segunda executa a mesma carga de trabalho em uma pilha OLAP. Escolhi a pilha OLAP por causa de uma única otimização, mas precisei entender todo o lakehouse para aproveitá-la.
O design do InnoDB traz três garantias que moldaram minhas primeiras escolhas. Ele armazena todas as colunas de uma linha juntas, então buscar uma barra de um símbolo acessa um único ponto do disco, o que é adequado para a ingestão. No entanto, um indicador que precisa de apenas duas colunas ainda busca todas as colunas pelo buffer pool. Os índices aceleram as leituras, mas tornam as escritas mais lentas, pois cada escrita precisa atualizar cada árvore B da tabela. Isso é ótimo para leituras seletivas e péssimo para ingestão com muitas escritas, por isso minhas tabelas Raw* têm apenas uma chave primária.
O InnoDB também usa um undo log, que permite leituras e escritas concorrentes. Quando uma linha é atualizada ou excluída, o valor antigo é armazenado para que outras sessões ainda possam lê-lo. Inserções geram um undo log menor, que é descartado no commit. Os undo logs de atualizações e exclusões entram em uma lista global de histórico, que o InnoDB limpa depois que todas as sessões iniciadas antes do commit terminam. Esse mecanismo é o Multi-Version Concurrency Control, ou MVCC, que permite que inserções e atualizações ocorram sem bloquear as leituras.
Sem perceber, eu havia projetado meu banco de dados InnoDB com base em um fundamento OLAP. Minha tabela financialdata continha a data e hora junto com os preços OHLC, e cada indicador técnico exigia um join nela para encontrar a data. Foi um dos piores designs de dados que já fiz, e só percebi quando o banco passou de 100GB de dados. Corrigi-lo foi brutal.
Fonte: Hacker News · Resumido por HeadlinesBriefing