Pular para o conteúdo
Email Painel de controle Escolher plano

Otimizar o banco de dados na hospedagem: índices, consultas e cache

Otimizar o banco de dados na hospedagem: índices, consultas e cache

Em uma hospedagem compartilhada, um banco de dados lento quase sempre tem três causas: consultas sem o índice adequado, muitas consultas pequenas por página (o problema N+1) e resultados recalculados a cada visita em vez de ficarem em cache. Verifique as consultas lentas com EXPLAIN, crie índices compostos para WHERE e ORDER BY, troque laços por um JOIN e guarde as páginas prontas em cache. No nosso teste com 100.000 linhas, um índice reduziu uma consulta de catálogo de 20,41 ms para 0,27 ms.

Isso vale para MySQL e MariaDB em hospedagem compartilhada: você controla o seu banco de dados e o seu código, mas não as configurações do servidor. Todas as medições abaixo vêm do nosso servidor de testes e não são dados de produção da RichHost.

Como um banco de dados divide o servidor da hospedagem

Na hospedagem compartilhada, o seu banco de dados roda em um servidor MySQL ou MariaDB usado por várias contas. Para que um site não ocupe o servidor inteiro, os provedores definem limites por conta. MySQL e MariaDB já trazem limites de recursos para isso: MAX_USER_CONNECTIONS (conexões simultâneas), MAX_QUERIES_PER_HOUR, MAX_UPDATES_PER_HOUR e MAX_CONNECTIONS_PER_HOUR. Os limites de consultas são por hora, não por minuto. Os valores exatos são definidos pelo provedor; se não estiverem na descrição do plano, pergunte ao suporte.

Quando um limite é atingido, o servidor recusa a conexão ou a consulta. Para o teste, liberamos para uma conta 3 conexões e 500 consultas por hora e recebemos estes erros:

ERROR 1226: User 'site' has exceeded the 'max_user_connections' resource (current value: 3)
ERROR 1226: User 'site' has exceeded the 'max_queries_per_hour' resource (current value: 500)

No site, dependendo da aplicação, isso aparece como erro ao estabelecer conexão com o banco de dados no WordPress ou como erro 503 Service Unavailable. Na prática: quanto menos consultas uma página precisa, e quanto mais leves elas são, mais longe ela fica de qualquer limite.

Índices: primeiro, verifique com EXPLAIN

Criamos uma tabela de teste com 100.000 produtos e rodamos uma consulta típica de catálogo: os produtos de uma categoria, dos mais novos para os mais antigos. O EXPLAIN mostra como o servidor pretende executá-la:

EXPLAIN SELECT id, name, price FROM products
WHERE category_id = 42 ORDER BY created_at DESC LIMIT 20;

ALTER TABLE products ADD INDEX idx_cat_created (category_id, created_at);

A primeira linha é o resultado antes do índice; a segunda, depois:

type: ALL  key: NULL             rows: 99824  Extra: Using where; Using filesort
type: ref  key: idx_cat_created  rows: 500    Extra: Using where

Sem índice, o servidor leu todas as 100.001 linhas (contador Handler_read_rnd_next) e ainda as ordenou (Using filesort): mediana de 20,41 ms. Com o índice composto (category_id, created_at), ele leu 20 entradas do índice e não precisou ordenar: 0,27 ms. A ordem importa: primeiro a coluna comparada com =, depois a coluna de ordenação. É o padrão descrito na documentação do MySQL sobre ORDER BY.

Índices não são de graça. Segundo a documentação do MySQL, cada índice precisa ser atualizado em todo INSERT, UPDATE e DELETE, e índices desnecessários desperdiçam espaço. No nosso teste, inserir 50.000 linhas levou 197 ms só com a chave primária e 546 ms com quatro índices extras (mediana de 5 execuções). Os dois índices deste artigo ocupam 2,5 MB e 3,5 MB ao lado de 7,5 MB de dados da tabela, e na hospedagem esse espaço entra na sua cota de disco.

  • Indexe as colunas usadas em WHERE, JOIN e ORDER BY das consultas frequentes
  • Use índices compostos só se as consultas usarem a primeira coluna deles
  • Passe toda consulta lenta pelo EXPLAIN: type: ALL e Using filesort são sinais de alerta
  • Remova índices que nenhuma consulta frequente usa
  • Não crie índices “por precaução” em todas as colunas

LIKE ‘%…%’ não usa o índice

Um índice B-tree comum só ajuda o LIKE se o padrão não começar com curinga (documentação do MySQL). O teste na coluna indexada name:

SELECT COUNT(*) FROM products WHERE name LIKE 'Product 4242%';  -- type: range, rows: 11
SELECT COUNT(*) FROM products WHERE name LIKE '%4242 red%';     -- type: index, rows: 99824

A busca pelo começo leu 11 entradas do índice em 0,11 ms. A busca “em qualquer parte do texto” percorreu as 100.000 entradas do índice e levou 22,39 ms, mais do que a consulta de catálogo sem índice nenhum. Para buscar dentro de textos, use um índice FULLTEXT (MATCH ... AGAINST) ou um plugin de busca.

N+1: 51 consultas em vez de uma

O problema N+1 aparece quando o código carrega uma lista e depois faz uma consulta separada para cada item. Exemplo: uma página com 50 produtos e o nome do fabricante. Em cima, a variante N+1; embaixo, o mesmo conteúdo com um JOIN:

SELECT id, manufacturer_id, name FROM products ORDER BY id LIMIT 50;
SELECT name FROM manufacturers WHERE id = ?;   -- x 50

SELECT p.id, p.name, m.name AS manufacturer
FROM products p JOIN manufacturers m ON m.id = p.manufacturer_id
ORDER BY p.id LIMIT 50;

Por um socket local, a variante N+1 levou 5,43 ms de mediana e o JOIN, 0,29 ms (200 execuções). Em uma hospedagem real, cada uma das 51 consultas ainda soma a ida e volta até o servidor de banco de dados. Os limites pesam ainda mais: com 500 consultas por hora, a variante N+1 atendeu 9 visualizações de página e a variante JOIN, 499.

Gráfico: tempo mediano das consultas de teste com e sem índice, com LIKE e N+1 contra JOIN
Um índice adequado e um JOIN são o que mais economiza tempo
Infográfico: 5 passos para otimizar o banco de dados na hospedagem

Cache: o que funciona hoje

É comum ler que toda consulta vai ao disco. Não é bem assim: o InnoDB mantém na memória RAM os dados de tabelas e índices mais usados, no buffer pool. Mesmo assim, uma consulta repetida precisa ser analisada e executada toda vez, e cada uma conta nos limites. Um cache na aplicação economiza justamente esse trabalho.

Método Onde ficam os dados O que economiza Limitações
Cache de página (plugin ou servidor) Arquivos ou RAM do servidor A página inteira para visitantes anônimos, sem PHP nem banco de dados Usuários logados, carrinho e formulários exigem exceções
Cache de objetos persistente (Redis, Memcached) RAM de um serviço separado Consultas repetidas e resultados calculados O serviço precisa rodar no servidor; na hospedagem compartilhada depende do provedor
Query cache do MySQL/MariaDB Servidor de banco de dados Hoje, praticamente nada Removido no MySQL 8.0; desativado por padrão no MariaDB e escala mal em servidores multinúcleo
Cache do navegador e CDN Navegador, nós da CDN Arquivos estáticos (imagens, CSS, JS) Não reduz as consultas ao banco das páginas dinâmicas

No WordPress, o cache de objetos não é persistente por padrão: os dados em cache só existem durante uma requisição, a menos que você instale um plugin de cache persistente. Sem Redis ou Memcached, o maior ganho vem de um cache de página para visitantes anônimos; veja como acelerar o WordPress.

Outros erros comuns

  1. SELECT * sem LIMIT: a consulta traz todas as linhas e colunas, embora a página mostre só 10. Escolha as colunas necessárias e limite o número de linhas.
  2. Arquivos dentro do banco: imagens, PDFs e grandes blocos JSON incham as tabelas e os backups. Guarde os arquivos no sistema de arquivos e, no banco, apenas o caminho.
  3. Tipo pequeno demais para AUTO_INCREMENT: TINYINT vai até 127 (255 se unsigned) e depois a inserção falha. No nosso teste, a 128ª linha foi recusada com ERROR 167: Out of range value. O WordPress usa BIGINT UNSIGNED nas suas colunas de ID.
Tela com logs do servidor e métricas de monitoramento em tempo real

Monitoramento na hospedagem compartilhada: o que você consegue ver

A principal ferramenta é o log de consultas lentas (slow query log). Ele vem desativado por padrão, o limite long_query_time é de 10 segundos e ativá-lo é uma configuração global: o MariaDB exige o privilégio SUPER e o MySQL, SYSTEM_VARIABLES_ADMIN. Uma conta comum de hospedagem recebe isto:

SET GLOBAL slow_query_log = 1;
ERROR 1227: Access denied; you need (at least one of) the SUPER privilege(s) for this operation

Por isso, na hospedagem compartilhada, peça um trecho do log ao suporte ou meça pelo lado da aplicação. No WordPress, o plugin Query Monitor aponta consultas lentas, duplicadas e com erro e mostra de qual plugin ou tema elas vêm. Sem o privilégio PROCESS, o SHOW PROCESSLIST mostra apenas as suas próprias conexões: útil para achar uma consulta travada, mas não para avaliar a carga do servidor. Tudo isso faz parte do monitoramento do servidor e da hospedagem.

  • Número de consultas por página e consultas duplicadas
  • As consultas mais lentas e o EXPLAIN delas
  • Erros 1226 e erros de conexão com o banco de dados
  • Tamanho do banco e maiores tabelas
  • Tempo de resposta das páginas ao longo do tempo

Sintoma e solução

Sintoma O que verificar O que fazer
Página de categoria ou listagem lenta EXPLAIN: type: ALL, Using filesort Índice composto: coluna do WHERE e depois a do ORDER BY
Busca do site lenta LIKE '%...%' na consulta Índice FULLTEXT ou plugin de busca; um índice comum não ajuda aqui
Dezenas de consultas parecidas por página Query Monitor: consultas duplicadas JOIN ou carregar os dados relacionados em uma única consulta
Erro 1226 ou erro de conexão com o banco Consultas e conexões por página Reduzir consultas, ativar cache de página, perguntar os limites ao provedor
As mesmas páginas são geradas de novo para cada visitante Existe cache de página? Ativar cache de página para visitantes anônimos
Uma tabela continua grande depois de exclusões em massa Espaço não usado na tabela OPTIMIZE TABLE em um horário tranquilo

Na RichHost, os sites rodam em planos de hospedagem com armazenamento NVMe e painel de controle próprio com assistente de IA, em servidores na Europa e nos EUA. As regras acima valem da mesma forma: menos consultas, e mais leves, significam páginas mais rápidas e mais folga em relação a qualquer limite. Para projetos com WordPress, veja também a nossa página de hospedagem WordPress.

Como verificamos: executamos as consultas em um servidor de testes com MariaDB 10.11.14 (contêiner Ubuntu 24.04, 2 vCPU Intel Xeon 2,1 GHz, 8 GB de RAM, configurações padrão, buffer pool do InnoDB de 128 MB) com tabelas de teste de 100.000 produtos e 500 fabricantes. Os tempos são medianas de 50 execuções (N+1 e JOIN: 200) por um socket local com Python e PyMySQL; em uma hospedagem real soma-se a latência de rede. Os limites da conta (3 conexões, 500 consultas por hora) foram definidos por nós para o teste: não são limites da RichHost nem de outro provedor, e esses números não são dados de produção da RichHost. Fatos da documentação oficial: MySQL 8.4 (índices, LIKE, ORDER BY, limites de recursos, SHOW PROCESSLIST, slow query log, buffer pool, AUTO_INCREMENT, OPTIMIZE TABLE), query cache do MySQL 5.7, query cache do MariaDB, WordPress (WP_Object_Cache, requisitos, Query Monitor). Verificado em 30/10/2026.

Perguntas frequentes

Quantos índices são demais?

Não existe um número fixo. Cada índice acelera certas leituras e deixa toda gravação mais lenta: no nosso teste, quatro índices extras deixaram a inserção cerca de 2,8 vezes mais lenta. Mantenha os índices que o EXPLAIN realmente mostra nas suas consultas frequentes.

O OPTIMIZE TABLE acelera o banco de dados?

Raramente. No InnoDB, o OPTIMIZE TABLE reconstrói a tabela (ALTER TABLE ... FORCE), atualiza as estatísticas dos índices e libera o espaço não usado. Ajuda depois de exclusões em massa, mas não substitui um índice que está faltando.

Posso ativar o log de consultas lentas na hospedagem compartilhada?

Em geral não por conta própria, porque é preciso ter SUPER (MariaDB) ou SYSTEM_VARIABLES_ADMIN (MySQL). Peça ao suporte ou use o Query Monitor no WordPress.

Vale a pena ativar o query cache?

Não. Ele foi removido no MySQL 8.0, vem desativado por padrão no MariaDB e, segundo a documentação, escala mal em servidores multinúcleo sob carga. Aposte no cache de página e no cache de objetos.

Qual versão de banco de dados o WordPress precisa?

O WordPress recomenda MariaDB 10.11 ou superior, ou MySQL 8.0 ou superior. Para saber qual versão a sua hospedagem usa, veja no phpMyAdmin ou rode SELECT VERSION();.

Mais sobre este tema

Todos os artigos
Site lento ou erros 5xx: diagnóstico em hospedagem compartilhada
Resolução de problemas de hosting25.08.2026

Site lento ou erros 5xx: diagnóstico em hospedagem compartilhada

Como descobrir passo a passo por que um site em hospedagem compartilhada está lento ou retorna erros 5xx: TTFB com curl, códigos…

Limite de inodes na hospedagem: disco livre, mas sem novos arquivos
Hosting partilhado27.07.2026

Limite de inodes na hospedagem: disco livre, mas sem novos arquivos

Espaço livre em disco, mas nenhum arquivo novo: o que é um inode, que erros o WordPress mostra, quantos inodes ocupam cache,…

Logs do servidor: como ler o log de acesso e o log de erros
Guias e tutoriais de hosting02.06.2026

Logs do servidor: como ler o log de acesso e o log de erros

Onde encontrar os logs do site na hospedagem, a diferença entre log de acesso e log de erros, e comandos testados: IPs…