Como corrigir as queries lentas do JetEngine no banco de dados
O que é as queries lentas do JetEngine no banco?
As queries lentas do JetEngine no banco são consultas montadas pelo Query Builder que demoram muito para retornar e seguram a renderizacao do Listing Grid, do Dynamic Table ou do Map Listing. O Query Builder e a ferramenta do JetEngine, em JetEngine -> Query Builder, que monta a consulta ao banco (Posts Query, Terms Query, Users Query, SQL Query, entre outras) e entrega o resultado ao widget. Quando essa query filtra por muitos campos de metadados, usa SQL que varre a tabela inteira ou roda sem o Cache Query ligado, cada visita a página obriga o MySQL a refazer o trabalho, o tempo de resposta sobe e o TTFB da página dispara.
Como identificar
- A página com o Listing Grid do JetEngine leva vários segundos para abrir, enquanto outras páginas do mesmo site respondem rápido.
- O Query Monitor lista a query do JetEngine entre as Slowest Queries, com tempo acima de meio segundo e a clausula com JOIN na tabela wp_postmeta.
- Com o slow query log do MySQL ligado, a consulta do Listing aparece registrada por ultrapassar o long_query_time configurado.
- O Listing Grid com paginação fica mais lento a cada página, e os filtros do JetSmartFilters demoram para aplicar.
- Com muitos acessos simultaneos, o uso de CPU do MySQL sobe e o host aponta limite de processos do banco atingido.
Como prevenir
- Mantenha o Cache Query ligado nas queries do Query Builder e so desative quando a query realmente precisar de dado sempre atualizado
- Prefira Posts Query com poucos filtros de Meta Query a uma SQL Query manual, e quando usar SQL garanta indice na coluna do filtro
- Use paginação e um Posts Per Page moderado no Listing Grid em vez de carregar centenas de registros de uma vez
- Monitore as páginas com Listing Grid pelo Query Monitor e pelo slow query log, agindo assim que uma query passar de meio segundo
- Mantenha um cache de objetos persistente (Redis ou Memcached) ativo para servir os resultados da query da memória
Causa
- Uma Meta Query do Query Builder filtrando por vários campos de metadados gera múltiplos JOIN na tabela wp_postmeta, que não tem indice em meta_value, forcando o MySQL a varrer milhares de linhas por requisicao.
- O toggle Cache Query da query, ligado por padrão, foi desativado no Query Builder, entao o JetEngine reexecuta a consulta inteira no banco a cada carregamento da página em vez de reaproveitar o resultado.
- Uma query do tipo SQL Query escrita sem clausula WHERE seletiva ou sem indice na coluna usada no filtro, fazendo o banco ler a tabela inteira (full table scan) para montar o Listing.
- Posts Per Page alto ou ausencia de paginação no Listing Grid, pedindo centenas de registros de uma vez e inflando o conjunto de dados que o banco precisa ordenar e devolver.
- Ausencia de cache de objetos persistente (Redis ou Memcached), obrigando o banco a refazer a query do Query Builder a cada visita em vez de servir o resultado da memória.
- Relations Query ou Meta Query com ordenacao por um meta field não indexado, fazendo o MySQL montar uma tabela temporaria e ordenar em disco a cada requisicao.
Como resolver
- Confirme qual query do Query Builder esta lenta: instale o Query Monitor e abra a página lenta. Na aba de banco, ordene por tempo e identifique a consulta do JetEngine que aparece entre as mais lentas e a tabela que ela toca, geralmente wp_posts com JOIN em wp_postmeta. Isso confirma que o gargalo e a query do Listing, e não outra coisa.
WP Admin -> Plugins -> instalar e ativar Query Monitor Abrir a página lenta -> Query Monitor -> Queries -> Slowest -> localizar a query do JetEngine - Garanta que o Cache Query da query esteja ligado: abra a query no Query Builder e confirme que o switcher Cache Query, ligado por padrão, não foi desativado. Com ele ligado, o JetEngine reaproveita o resultado em vez de refazer a consulta a cada carregamento. So mantenha desligado se a query precisa de dado sempre fresco.
WP Admin -> JetEngine -> Query Builder -> abrir a query -> General Settings -> Cache Query (ON) - Reduza a Meta Query e a quantidade de itens por página: abra as condicoes da query e remova os filtros de Meta Query que não são essenciais, pois cada um adiciona um JOIN na wp_postmeta. No widget, baixe o Posts Per Page e ligue a paginação para o banco devolver menos linhas por requisicao.
WP Admin -> JetEngine -> Query Builder -> abrir a query -> Meta Query -> remover condicoes não essenciais Editor -> Listing Grid -> Settings -> Posts Per Page -> reduzir o número Editor -> Listing Grid -> ligar paginação - Meça a query no slow query log e leia o plano de execução: ative o slow query log do MySQL para capturar a consulta lenta e rode um EXPLAIN sobre ela. O plano mostra se o banco esta fazendo varredura completa (type ALL) e qual coluna precisaria de indice. So depois disso você sabe onde criar o indice em vez de adivinhar.
SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 0.5; EXPLAIN SELECT ... ; - Crie um indice para a coluna filtrada na SQL Query: quando a query e do tipo SQL Query e o EXPLAIN apontou varredura completa, adicione um indice na coluna usada no filtro ou na ordenacao da sua tabela. Faca isso com backup do banco, porque criar indice em tabela grande bloqueia escrita por alguns instantes.
ALTER TABLE wp_minha_tabela ADD INDEX idx_campo (campo); - Ative um cache de objetos persistente: configure Redis ou Memcached como cache de objetos do WordPress. Com ele, o resultado da query do Query Builder fica em memória e e servido sem bater no banco a cada visita, o que corta o tempo de resposta nas páginas com Listing Grid.
WP Admin -> Plugins -> ativar o plugin de Redis Object Cache do seu host WP Admin -> Settings -> confirmar Object Cache: Connected
-- 1) Ligar o slow query log para capturar as consultas do JetEngine que demoram
-- mais de 0,5s (rode no banco; em producao prefira via my.cnf):
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 0.5;
-- 2) Plano de execucao de uma Meta Query tipica do Listing Grid.
-- type = ALL e rows altíssimo indicam varredura completa por falta de indice:
EXPLAIN
SELECT p.ID
FROM wp_posts AS p
INNER JOIN wp_postmeta AS pm ON ( p.ID = pm.post_id )
WHERE p.post_type = 'meu_cpt'
AND p.post_status = 'publish'
AND pm.meta_key = 'preco'
AND pm.meta_value > '1000'
ORDER BY pm.meta_value + 0 ASC;
-- 3) Quando a query e do tipo SQL Query sobre tabela propria, criar indice na
-- coluna do filtro/ordenacao remove a varredura completa (troque pelos nomes reais):
ALTER TABLE wp_minha_tabela ADD INDEX idx_campo (campo);














