🎉 USE O CUPOM FIM.DE.SEMANA.FULL | 20% OFF acima de R$ 100,00

Como corrigir queries lentas no banco com JetEngine e ACF PRO no WordPress

Time Full Services Time Full Services
Tipo Performance & Velocidade
Nome do erro Queries lentas do JetEngine e ACF PRO no banco EN: Slow database queries with JetEngine and ACF PRO
Severidade Grave
Descrição As queries lentas do JetEngine e ACF PRO no banco acontecem quando listings e filtros disparam meta_query pesadas sobre a tabela wp_postmeta sem indice útil, ou quando muitos campos são gravados como meta em vez de uma tabela dedicada, forçando JOINs e leituras caras a cada carregamento.

O que é queries lentas do JetEngine e ACF PRO no banco?

As queries lentas do JetEngine e ACF PRO no banco são consultas SQL que demoram para retornar porque dependem da tabela wp_postmeta. Tanto o ACF PRO quanto o JetEngine, na configuração padrão, gravam cada campo personalizado como uma linha em wp_postmeta (pares meta_key e meta_value). Quando um JetEngine Listing Grid filtra ou ordena por esses campos, o WordPress monta uma WP_Meta_Query que faz um JOIN em wp_postmeta para cada condicao. A coluna meta_value e do tipo LONGTEXT e não tem indice útil, entao o MySQL varre muitas linhas para resolver o filtro, e o tempo de resposta cresce com o tamanho da tabela.

Em sites com muitos posts e muitos campos por post, a wp_postmeta passa de centenas de milhares de linhas e cada listagem vira uma consulta cara. O resultado e TTFB alto, picos de CPU no banco e timeouts em páginas de arquivo, busca e filtros AJAX. A documentação de performance do WordPress reforça que ler dados do banco a cada carregamento, sem um cache de objeto persistente, sobrecarrega o servidor de banco em horarios de pico. Resolver passa por medir a query real, reduzir o peso da meta_query e mover dados de grande volume do wp_postmeta para uma estrutura própria, como os Custom Content Types do JetEngine.

Como identificar

  • Páginas com JetEngine Listing Grid demoram vários segundos para carregar e o TTFB sobe em arquivos, busca e filtros.
  • O filtro AJAX do JetSmartFilters trava ou retorna com atraso ao combinar mais de um campo do ACF ou do JetEngine.
  • O log de consultas lentas (slow query log) registra SELECT com vários JOIN na tabela wp_postmeta e clausula meta_value.
  • O Query Monitor mostra uma única query de listagem consumindo a maior parte do tempo total da página.
  • O uso de CPU do MySQL dispara e aparecem timeouts ou erro ‘MySQL server has gone away’ em horarios de pico de acesso.
Antes de começar: Antes de criar indices, rodar comandos no MySQL ou migrar campos para Custom Content Types, faça um backup completo do site (arquivos e banco de dados) ou teste primeiro em um ambiente de staging. Criar indice em uma wp_postmeta grande bloqueia a tabela durante a operacao e pode deixar o site indisponivel se feito direto em producao.

Como prevenir

  • Planeje desde o inicio onde cada dado mora: campos pontuais por post como meta do ACF ou JetEngine, e dados de alto volume em Custom Content Types do JetEngine, que gravam em tabela própria.
  • Sempre ative paginação ou lazy load nos Listing Grids e limite os itens por página, evitando consultas que retornam milhares de linhas em um único request.
  • Mantenha um cache de objeto persistente (Redis ou Memcached) ativo em producao para servir consultas repetidas da memória, conforme recomenda a documentação de performance do WordPress.
  • Monitore o crescimento da wp_postmeta e o slow query log periodicamente, para detectar meta_query pesadas antes de virarem gargalo em horario de pico.

Causa

  • Os campos do ACF PRO e do JetEngine são gravados como meta em wp_postmeta, e o Listing Grid filtra ou ordena por eles, gerando uma WP_Meta_Query com um JOIN em wp_postmeta para cada condicao do filtro.
  • A coluna meta_value de wp_postmeta e LONGTEXT e não possui indice por valor, entao filtros do tipo meta_value LIKE ou comparacoes numericas forçam o MySQL a varrer a tabela inteira em vez de usar indice.
  • O JetEngine Listing Grid esta configurado para trazer todos os posts de uma vez (sem paginação ou lazy load), montando uma consulta que retorna e ordena milhares de linhas em um único request.
  • Dados de alto volume (catalogos, diretorios, relacionamentos) estão armazenados como meta de post em vez dos Custom Content Types do JetEngine, que gravam em tabela própria, inchando o wp_postmeta para centenas de milhares de linhas.
  • Não ha cache de objeto persistente (Redis ou Memcached) ativo, entao a mesma consulta de listagem e refeita no banco a cada carregamento, em vez de ser servida da memória, sobrecarregando o MySQL nos picos de tráfego.

Como resolver

  1. Identifique a query lenta com o Query Monitor: Instale o plugin Query Monitor e abra a página lenta logado como administrador. No painel Database Queries, ordene por tempo e localize a consulta de listagem com vários JOIN em wp_postmeta. Anote o tempo, a tabela e as clausulas meta_key envolvidas antes de mudar qualquer coisa.
    Painel WP -> Plugins -> Adicionar novo -> instale e ative o Query Monitor
    Abra a página lenta e clique no menu do Query Monitor na barra superior
    Va em Queries -> Database Queries e ordene a coluna de tempo do maior para o menor
  2. Ative o slow query log do MySQL para confirmar o gargalo: Habilite o log de consultas lentas no MySQL para capturar as queries que passam do limite de tempo. Isso confirma se o gargalo e a meta_query sobre wp_postmeta e da a consulta exata para otimizar. Em hospedagem gerenciada, ative pelo painel ou pelo suporte.
    SET GLOBAL slow_query_log = 'ON';
    SET GLOBAL long_query_time = 1;
    SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
    EXPLAIN SELECT ... -- rode EXPLAIN na query capturada para ver os JOIN em wp_postmeta
  3. Reduza o peso do Listing Grid e do filtro: No JetEngine, edite o Listing Grid e ative a paginação ou o lazy load para não trazer todos os posts de uma vez, e limite o número de itens por página. Reduza também a quantidade de campos meta usados como filtro e ordenacao para diminuir o número de JOIN na consulta.
    Editor da página -> selecione o widget JetEngine Listing Grid
    Ative 'Lazy load' ou 'Use load more' e defina 'Posts per page' para um valor baixo (ex.: 12)
    Remova do filtro e da ordenacao os campos meta que não são essenciais
  4. Adicione um indice composto em wp_postmeta para as meta_keys quentes: Para os campos mais filtrados, crie um indice composto em (meta_key, meta_value) com um prefixo de tamanho, permitindo que o MySQL use indice em vez de varrer a tabela. Faça backup antes, porque a criação de indice em wp_postmeta grande bloqueia a tabela durante a operacao.
    CREATE INDEX full_meta_key_value ON wp_postmeta (meta_key(64), meta_value(64));
    ANALYZE TABLE wp_postmeta;
    EXPLAIN SELECT ... -- confirme que a query agora usa o novo indice na coluna key
  5. Migre dados de alto volume para Custom Content Types do JetEngine: Para catalogos e diretorios grandes, troque os campos meta por Custom Content Types do JetEngine, que gravam em uma tabela própria em vez do wp_postmeta. Consultas em tabela dedicada com colunas indexadas substituem os JOIN caros de meta_query e reduzem o tamanho da wp_postmeta.
    Painel WP -> JetEngine -> Custom Content Types -> Add New
    Defina os campos como colunas do Content Type (gravadas em tabela própria, fora do wp_postmeta)
    Reaponte os Listing Grids para o Content Type e remova os campos meta antigos após validar
  6. Ative um cache de objeto persistente: Ative Redis ou Memcached como cache de objeto persistente para evitar refazer a mesma consulta no banco a cada carregamento. A documentação de performance do WordPress aponta que, sem esse cache, o servidor le do banco em todo page view e sobrecarrega o MySQL nos picos.
    Confirme com a hospedagem que ha Redis ou Memcached disponível
    Painel WP -> Plugins -> instale um plugin de object cache (ex.: Redis Object Cache) e clique em 'Enable Object Cache'
    Recarregue a página lenta e compare o tempo total no Query Monitor
PHP
<?php
/**
 * Tira do filtro AJAX do JetEngine os campos meta mais pesados,
 * substituindo a comparacao por meta_value (sem indice em wp_postmeta)
 * por um filtro de taxonomia indexado, que usa o term_relationships.
 *
 * Coloque no functions.php do tema filho ou em um plugin proprio.
 */
add_action( 'pre_get_posts', 'full_jetengine_otimiza_listing' );
function full_jetengine_otimiza_listing( $query ) {
    if ( is_admin() || ! $query->is_main_query() ) {
        return;
    }

    // Aplica so na listagem do catalogo (ajuste o post_type).
    if ( 'catalogo' !== $query->get( 'post_type' ) ) {
        return;
    }

    // 1) Pagina os resultados: evita trazer milhares de linhas de uma vez.
    $query->set( 'posts_per_page', 12 );

    // 2) Nao calcula o total de linhas encontradas (SQL_CALC_FOUND_ROWS),
    //    que e caro em tabelas grandes quando a paginacao exata nao e critica.
    $query->set( 'no_found_rows', true );

    // 3) Troca o filtro por meta_value (LONGTEXT sem indice) por taxonomia,
    //    que resolve via term_relationships indexado em vez de JOIN no wp_postmeta.
    $marca = isset( $_GET['marca'] ) ? sanitize_title( wp_unslash( $_GET['marca'] ) ) : '';
    if ( $marca ) {
        $query->set( 'meta_query', array() ); // remove a meta_query pesada
        $query->set( 'tax_query', array(
            array(
                'taxonomy' => 'marca',
                'field'    => 'slug',
                'terms'    => $marca,
            ),
        ) );
    }
}

Perguntas frequentes

Por que o JetEngine e o ACF PRO deixam o banco lento
Porque, na configuração padrão, ambos gravam cada campo como uma linha em wp_postmeta. Quando um Listing Grid filtra por esses campos, o WordPress monta uma meta_query com um JOIN em wp_postmeta por condicao, e a coluna meta_value não tem indice útil, entao o MySQL varre muitas linhas a cada carregamento.
Como descobrir qual query do JetEngine esta lenta
Use o plugin Query Monitor logado como administrador e abra o painel Database Queries na página lenta, ordenando por tempo. Confirme com o slow query log do MySQL e rode EXPLAIN na consulta para ver os JOIN em wp_postmeta e validar que a meta_query e o gargalo.
Criar indice em wp_postmeta resolve as queries lentas do JetEngine
Ajuda nos campos mais filtrados, porque um indice composto em meta_key e um prefixo de meta_value permite ao MySQL usar indice em vez de varrer a tabela. Faça backup antes, já que criar indice em uma wp_postmeta grande bloqueia a tabela durante a operacao.
O que são Custom Content Types do JetEngine e por que ajudam na performance
São um recurso do JetEngine que armazena dados em uma tabela própria do banco, em vez de gravar tudo como meta no wp_postmeta. Consultas em tabela dedicada com colunas indexadas substituem os JOIN caros de meta_query, reduzem o tamanho do wp_postmeta e aceleram listagens de alto volume.
Vale a pena migrar campos do ACF para Custom Content Types
Vale quando o volume e alto, como catalogos e diretorios com muitos itens e filtros. Campos pontuais por post podem continuar como meta do ACF, mas dados que alimentam listagens grandes ganham muito ao sair do wp_postmeta para uma tabela dedicada do Content Type.
O cache de objeto resolve sozinho as queries lentas
Não sozinho, mas ajuda muito. A documentação de performance do WordPress aponta que sem um cache de objeto persistente o servidor le do banco a cada page view. Com Redis ou Memcached, consultas repetidas vem da memória, mas a meta_query pesada ainda deve ser reduzida ou movida para tabela própria.
Por que o filtro AJAX do JetSmartFilters fica lento
Porque cada campo combinado no filtro adiciona uma condicao a meta_query, e cada condicao vira um JOIN em wp_postmeta. Quanto mais campos meta no filtro e quanto maior a tabela, mais cara a consulta. Reduzir o número de campos filtraveis e paginar os resultados alivia o banco.
Posso apenas aumentar os recursos do servidor em vez de otimizar a query
Mais CPU e memória adiam o problema, mas não corrigem a causa: a meta_query continua varrendo wp_postmeta a cada carregamento. Conforme o site e a tabela crescem, o gargalo volta. Otimizar a consulta, indexar e mover dados de volume para tabela própria e a correção duradoura.

Seja PRO.

Tenha acesso a snippets de código premium — PHP, JavaScript, CSS e HTML prontos para usar em seus projetos.

Conhecer o plano Pro →

Uma nova era para o WordPress.

A FULL Services redefine o CMS com uma arquitetura modular que transforma o WordPress em um motor de crescimento digital. 

Painéis personalizados

Um novo nível de controle para o WordPress. Acompanhe métricas, automações e evolução do seu site em um único painel visual.

A força por trás de grandes marcas

Para agências, estúdios e profissionais independentes que desejam oferecer soluções de alto nível com sua própria marca.

Componentes

Hero Sections

30 componentes

Seções de CTA

14 componentes

Login

14 componentes

Blog

14 componentes

Cabeçalhos

24 componentes

Seções de FAQ

53 componentes

Cadastro

53 componentes

Blog individual

53 componentes

Rodapés

28 componentes

Seções de contato

27 componentes

Seções de preços

27 componentes

Faixas

27 componentes

Portfólio

16 componentes

Seções de equipe

12 componentes

Números

12 componentes

Logotipos

12 componentes