
Imagine o seguinte cenário: você tem um banco de dados MySQL rodando a operação da sua empresa com perfeição. Mas aí surge a necessidade de extrair relatórios complexos, médias e KPIs de tabelas com milhões de linhas. O resultado? Queries que demoram minutos, índices secundários que incham o disco e a performance da aplicação transacional (OLTP) começando a sofrer.
Para resolver isso, muitos partem para arquiteturas complexas de ETL e Data Warehouses externos. Mas e se você pudesse ter o poder analítico de um banco colunar dentro do MySQL que você já confia? É aqui que entra o MySQL HeatWave.
Engines Colunares:
Todos estamos bem ambientados quando se trata de tabelas com linhas e colunas, essa visualização mental é bem simples e efetiva. Porém, esse modelo traz consigo uma característica que limita muito o poder de processamento. Vamos para um exemplo bem simples:
| Nome | Profissão | Gênero | Idade |
| Roberto | DBA | Masculino | 20 |
| Sérgio | Financeiro | Masculino | 36 |
| Luana | Marketing | Feminino | 34 |
Temos os seguintes dados acima e uma simples pergunta: qual a média da idade? Parece tão simples responder, certo?
Fazemos 20 + 36 = 56 +34 = 90 / 3 = 30. Mas tenho certeza que quando você olhou os números, você não leu as linhas, você ignorou as outras informações e focou apenas na coluna de Idade, certo?
Engines colunares, fazem exatamente o mesmo. Diferente de engines transacionais (como o InnoDB), onde o banco precisa ler a linha inteira do disco para a memória apenas para extrair um campo, uma engine colunar isola apenas os dados da coluna necessária.
Como os dados da coluna Idade estão armazenados fisicamente juntos, o sistema consegue ler centenas de idades em uma única operação de I/O, enquanto no modelo tradicional, ele daria saltos na memória, desperdiçando processamento com dados que você não pediu (como Nome ou Profissão). Não é diferente de uma biblioteca organizada por assuntos por exemplo, você não perde tempo andando pelo corredor de Culinária ou Autoajuda se o seu objetivo é História. No MySQL HeatWave, a CPU faz o mesmo: ela não gasta ciclos processando Nome ou Profissão se a sua query só pediu Idade. É eficiência pura de movimento e tempo.
O Coração do HeatWave: Massive Parallel Processing e SIMD
Mas não vai achando que é o MySQL HeatWave é apenas uma engine colunar como outras no mercado, ele vai bem mais fundo. Seguindo a analogia da biblioteca imagine que em vez de uma biblioteca só, temos várias. E aquela sua tabela gigantesca de vendas? Ela foi dividida: a Biblioteca A ficou com os dados de 2020, a B com 2021, e assim por diante. Quando você pergunta o total de vendas, todos os bibliotecários de todas as bibliotecas abrem seus respectivos livros ao mesmo tempo.
E não para por ai, o HeatWave vai além. Dentro de cada biblioteca, o bibliotecário não lê o livro sozinho. Ele divide as páginas para cada assistente (CPU Core). Enquanto um assistente checa a primeira linha da página 1, outro já está checando a primeira linha da página 2. Isso é o Massive Parallel Processing (MPP): uma divisão brutal de trabalho onde ninguém fica parado esperando o outro terminar.
Já vimos que o ganho de performance aqui é brutal, mas tem uma coisa que eu não falei. E se eu te dissesse que esses assistentes são sobre-humanos? É aqui que entra o SIMD (Single Instruction, Multiple Data). Em vez de lerem palavra por palavra, eles conseguem escanear a página inteira com um único olhar, identificando instantaneamente todos os dados que você buscou. Eles não processam um dado por vez, eles processam um vetor (um bloco) de dados de uma só vez.
Para fixar na mente, vamos voltar ao exemplo da tabela:
| Nome | Profissão | Gênero | Idade |
| Roberto | DBA | Masculino | 20 |
| Sérgio | Financeiro | Masculino | 36 |
| Luana | Marketing | Feminino | 34 |
A engine transacional, faria a leitura de todas as linhas, para então pegar cada valor da idade. A engine colunar isola e olha apenas para o dado que precisamos. Agora que temos todos os dados do mesmo tipo, o SIMD coloca esses valores em um vetor e executa a operação de uma só vez. Enquanto o MySQL tradicional faz 20 + 36, depois pega o resultado e faz + 34 (várias operações), o SIMD carrega os três valores e processa a soma em paralelo em um único ciclo de instrução. Onde o MySQL tradicional faz 3 operações para somar, o SIMD faz uma.
Até aqui, acredito que ficou claro que o MySQL HeatWave é otimizado a nível clocks no processamento, reduzindo o número de operações executadas pelo processador e trazendo máxima eficiência, tudo isso alinhado a múltiplos núcleos e nodes.
E para tornar tudo isso ainda mais interessante, todos os dados do HeatWave estão em memória RAM de altíssima velocidade, já pré-formatados e prontos para serem escaneados por esse exército de processadores. É o fim do gargalo de disco!
Obs: O HeatWave persiste os dados de forma otimizada e pronto para ser carregado caso o cluster for reiniciado.
Demonstração:
Para demonstrar o que isso tudo significa na prática, restaurei um banco que a tabela principal, possui cerca de 54 milhões de linhas e iremos executar alguns testes antes e depois de ativar e Engine RAPID que é responsável pela execução das queries no cluster HeatWave. No exemplo irei utilizar o Always Free que contempla os seguintes recursos:
- ECPU: 1
- RAM: 8GB
- Storage: 50GB
Conforme vemos abaixo, o COUNT leva 36 segundos para rodar em cerca de 54 milhões de linhas.
|
1 2 3 4 5 6 7 |
SELECT COUNT(*) FROM booking; +----------+ | COUNT(*) | +----------+ | 54304619 | +----------+ 1 row in set (36.8412 sec) |
Agora vamos rodar uma query pesada, que irá envolver alguns calculos e agregações para analisarmos como o MySQL se comporta:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
SELECT MAX(b.price) as mostexpensivebooking, AVG(b.price) as averagebookingprice, pd.country FROM booking b LEFT JOIN passenger p ON p.passenger_id = b.passenger_id LEFT JOIN passengerdetails pd ON pd.passenger_id = p.passenger_id GROUP BY pd.country LIMIT 10; +----------------------+---------------------+---------------+ | mostexpensivebooking | averagebookingprice | country | +----------------------+---------------------+---------------+ | 501.00 | 253.671192 | Canada | | 500.96 | 244.414026 | Ukraine | | 500.99 | 246.505494 | Kenya | | 501.00 | 251.796174 | United States | | 501.00 | 256.909427 | St Vincent | | 501.00 | 249.477601 | Brazil | | 501.00 | 249.659270 | India | | 501.00 | 250.900889 | New Zealand | | 501.00 | 254.237517 | Sweden | | 501.00 | 253.637465 | Cuba | +----------------------+------------ 10 rows in set (3 min 34.9543 sec) |
O MySQL levou 3.35 minutos para processar o resultado. Aqui seria o momento onde começaríamos a projetar a criação de índices secundários, mas sabemos que em tabelas dessa escala, a manutenção deles custa caro, ocupam espaço em disco e degradam a performance de escrita.
Por isso, vou seguir o teste com o MySQL HeatWave puro, sem índices adicionais. O objetivo é mostrar como a engine RAPID entrega performance e simplicidade, sem exigir que você vire um mestre do tuning para cada nova consulta.
Como fazemos isso? Simples, vamos rodar o seguinte comando:
|
1 |
CALL sys.heatwave_load(JSON_ARRAY("airportdb"), JSON_OBJECT("mode", "normal")); |
Vou deixar abaixo, na íntegra a saída do comando que executamos:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
+------------------------------------------+ | INITIALIZING HEATWAVE AUTO PARALLEL LOAD | +------------------------------------------+ | Version: 4.54 | | | | Load Mode: normal | | Load Policy: disable_unsupported_columns | | Output Mode: normal | | | +------------------------------------------+ 6 rows in set (0.0508 sec) +-----------------------------------------------------------------------------------------------+ | OFFLOAD ANALYSIS | +-----------------------------------------------------------------------------------------------+ | Verifying input schemas: 1 | | User excluded items: 0 | | | | SCHEMA OFFLOADABLE OFFLOADABLE SUMMARY OF | | NAME TABLES COLUMNS ISSUES | | ------ ----------- ----------- ---------- | | `airportdb` 14 105 1 table(s) are partially loadable | | | | Total offloadable schemas: 1 | | | +-----------------------------------------------------------------------------------------------+ 10 rows in set (0.0508 sec) +-----------------------------------------------------------------------------------------------------------------------------+ | CAPACITY ESTIMATION | +-----------------------------------------------------------------------------------------------------------------------------+ | Default encoding for string columns: VARLEN (unless specified in the schema) | | Estimating memory footprint for 1 schema(s) | | | | TOTAL ESTIMATED ESTIMATED TOTAL DICTIONARY VARLEN ESTIMATED | | SCHEMA OFFLOADABLE HEATWAVE NODE MYSQL NODE STRING ENCODED ENCODED LOAD | | NAME TABLES FOOTPRINT FOOTPRINT COLUMNS COLUMNS COLUMNS TIME | | ------ ----------- --------- --------- ------- ---------- ------- --------- | | `airportdb` 14 3.80 GiB 7.44 MiB 36 0 36 2.63 min | | | | Sufficient MySQL host memory available to load all tables. | | Sufficient HeatWave cluster memory available to load all tables. | | | +-----------------------------------------------------------------------------------------------------------------------------+ 12 rows in set (0.0508 sec) +---------------------------------------------------------------------------------------------------------------------------------------+ | EXECUTING LOAD SCRIPT | +---------------------------------------------------------------------------------------------------------------------------------------+ | HeatWave Load script generated | | Retrieve load script containing 43 generated DDL command(s) using the query below: | | Deprecation Notice: "heatwave_load_report" will be deprecated, please switch to "heatwave_autopilot_report" | | SELECT log->>"$.sql" AS "Load Script" FROM sys.heatwave_autopilot_report WHERE type = "sql" ORDER BY id; | | | | Adjusting load parallelism dynamically per internal/external table. | | Using current parallelism of 1 thread(s) as maximum for internal tables. | | | | Warning: Executing the generated script may alter column definitions and secondary engine flags in the schema | | | | Using SQL_MODE: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION | | | | Proceeding to load 14 table(s) into HeatWave. | | | | Applying changes will take approximately 2.63 min | | | +---------------------------------------------------------------------------------------------------------------------------------------+ 16 rows in set (0.0508 sec) +----------------------------------------+ | TABLE LOAD | +----------------------------------------+ | TABLE (1 of 14): `airportdb`.`airline` | | Commands executed successfully: 3 of 3 | | Warnings encountered: 0 | | Table load succeeded! | | Total columns loaded: 4 | | Table loaded using 1 thread(s) | | Elapsed time: 3.00 s | | | +----------------------------------------+ 8 rows in set (0.0508 sec) [...] +---------------------------------------------+ | TABLE LOAD | +---------------------------------------------+ | TABLE (14 of 14): `airportdb`.`weatherdata` | | Commands executed successfully: 3 of 3 | | Warnings encountered: 0 | | Table load succeeded! | | Total columns loaded: 9 | | Table loaded using 1 thread(s) | | Elapsed time: 11.47 s | | | +---------------------------------------------+ 8 rows in set (0.0508 sec) +----------------------------------------------------------------------------------+ | LOAD SUMMARY | +----------------------------------------------------------------------------------+ | | | SCHEMA TABLES TABLES COLUMNS LOAD | | NAME LOADED FAILED LOADED DURATION | | ------ ------ ------ ------- -------- | | `airportdb` 14 0 105 1.29 min | | | | Total errors encountered: 1 | | Total warnings encountered: 1 | | Retrieve the associated logs from the report table using the query below: | | SELECT log FROM sys.heatwave_autopilot_report WHERE type IN ('error', 'warn'); | | | +----------------------------------------------------------------------------------+ 11 rows in set (0.0508 sec) Query OK, 0 rows affected (0.0508 sec) |
E simples assim, em menos de 2 minutos carregamos os dados no HeatWave. Isso significa, que ele carregou todo o conteúdo do nosso database “airportdb“, e partir de agora os dados estão sendo sincronizados. Toda e qualquer alteração no MySQL, será refletida para o HeatWave Cluster automaticamente sem qualquer intervenção e trabalho de ETL.
Se verificarmos o gráfico de monitoramento do HeatWave Cluster data load progress, vemos que de fato os dados foram carregados em memória:
Agora, vamos executar o COUNT e veremos como o HeatWave se comporta:
|
1 2 3 4 5 6 7 |
SELECT COUNT(*) FROM booking; +----------+ | COUNT(*) | +----------+ | 54304619 | +----------+ 1 row in set (0.0454 sec) |
Tivemos um ganho enorme de performance! Um simples COUNT que levava 36 segundos, agora roda em apenas 45 milissegundos. Vamos dificultar um pouco mais e rodar a query mais pesada:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
SELECT MAX(b.price) as mostexpensivebooking, AVG(b.price) as averagebookingprice, pd.country FROM booking b LEFT JOIN passenger p ON p.passenger_id = b.passenger_id LEFT JOIN passengerdetails pd ON pd.passenger_id = p.passenger_id GROUP BY pd.country LIMIT 10; +----------------------+---------------------+------------------+ | mostexpensivebooking | averagebookingprice | country | +----------------------+---------------------+------------------+ | 500.98 | 246.410096 | Russia | | 500.98 | 262.376839 | Papua New Guinea | | 500.82 | 272.408650 | Korea | | 500.73 | 241.994110 | Mozambique | | 500.57 | 289.229863 | Hungary | | 500.47 | 259.042045 | Myanmar | | 500.57 | 233.203657 | Canary Is | | 500.96 | 261.276666 | Denmark | | 500.58 | 255.954884 | Botswana | | 499.10 | 220.160399 | Nicaragua | +----------------------+---------------------+------------------+ 10 rows in set (12.7050 sec) |
E tivemos outro salto de performance. Fomos de 3 minutos e 35 segundos, para 12 segundos.
Conclusão:
O MySQL HeatWave não é apenas sobre velocidade, é sobre agilidade operacional. Com ele você tem:
-
Zero ETL: Sem movimentação de dados.
-
Zero Maintenance: Esqueça o “over-indexing” para queries analíticas.
-
Tempo Real: O dado que acabou de entrar no InnoDB já está pronto para ser processado no HeatWave.
Ver um ganho de 17x rodando em uma instância Always Free mostra que o limite é apenas o hardware. Em um cluster de produção com múltiplos nós e processamento paralelo massivo (MPP), o que levava minutos passa a ser instantâneo.







