Como otimizar o site WP para milhões de postagens

19

Estou trabalhando em um site de uma empresa que provavelmente criará milhões de postagens por meio de um tipo de post personalizado. São orações, portanto, basicamente, o usuário no front-end envia uma frase curta por meio de um formulário. A empresa se preocupa apenas com o conteúdo da postagem e a data da postagem. O site ainda nem foi lançado e eles já têm mais de 120.000 posts, por isso falo sério quando digo milhões.

Então, algumas perguntas de otimização:

  1. Digamos que eu tenha uma categoria 'em destaque' em um tipo de postagem personalizada com 500.000 postagens. A categoria em destaque possui apenas 500 postagens. Se eu criar uma consulta para as postagens em destaque, estou consultando as 500.000 postagens inteiras ou apenas as 500 em destaque? E se eu quiser exibir apenas as dez postagens mais recentes em destaque?
  2. Ao salvar esse tipo de postagem personalizado no banco de dados, há algo que eu posso fazer para reduzir os recursos do servidor, especialmente porque a única coisa realmente necessária é o conteúdo da postagem e a data?
  3. Devo usar um tipo de postagem personalizado? Gosto disso em princípio porque está bem integrado ao administrador do WordPress, mas se houver desvantagens significativas no desempenho, suponho que posso fazer algo diferente.

Eu nunca trabalhei em um projeto nessa escala, então estou um pouco mais preocupado com o desempenho do que o normal. Obrigado por qualquer ajuda!

Jeremiah Prummer
fonte
É importante manter as consultas ao banco de dados no mínimo em suas funções do WordPress e chamar scripts adequadamente, mas uma grande parte da otimização tem a ver com a forma como o servidor está instalado e configurado. Para isso, procure na rede de falha do servidor. serverfault.com/search?q=optimize+wordpress
iyrin
@RyanLoremIpsum - obrigado pelo comentário, mas esperava respostas para minhas perguntas específicas. A maioria do que eu encontrei lá lida com o próprio servidor, e não como WordPress opera e como otimizá-lo de uma perspectiva de código
Jeremias Prummer

Respostas:

25

1. Defina a consulta antes da execução do WP_Query

Isso parece ser o mais importante a ser lembrado ao tentar manter as consultas ao banco de dados no mínimo, já que a única oportunidade de alterar a consulta é, é claro, antes de ser executada no banco de dados SQL.

Consultas normais
Para uma consulta normal, o WordPress usa a wp()função, que por sua vez chama $wp->main( $query_vars ). As "variáveis ​​is_" das tags condicionais são definidas antes de passá-las para WP_Query->get_posts(), o que a converte em uma consulta ao banco de dados MySQL e finalmente as armazena no objeto $ wp_query. É possível filtrar a consulta antes que ela seja realmente executada no banco de dados SQL .

A pre_get_postsação se conecta a esse processo, permitindo que você altere a consulta antes de ser passada para WP_Query->get_posts().

Por exemplo, se você deseja filtrar a consulta por postagens na categoria "em destaque", use add_action( 'pre_get_posts', 'your_function_name' );e inclua a in_categorytag condicional your_function_name.

function your_function_name( $query ) {
    if ( $query->in_category( 'featured' ) && $query->is_main_query() ) {
        // Replace 123 with the category ID of the featured category.
        $query->set( 'cat', '123' );
    }
}
add_action( 'pre_get_posts', 'your_function_name' );

Veja API Plugin / Referência de Ação / pre get posts «WordPress Codex

Solicitações
de página Quanto aos modelos de página, como a página de arquivo da categoria "em destaque", as tags condicionais não funcionarão no pre_get_postsfiltro. Por exemplo, você não pode usar is_categorya verificação da página de arquivamento porque o WP_Query não foi executado.

Em vez disso, você teria que alterar a consulta principal para solicitações de página com uma new WP_Queryque seria algo parecido $query = new WP_Query( 'cat=123' );. Isso executa a consulta com o argumento apropriado definido desde o início.

Consulte Referência da classe / consulta WP «WordPress Codex

2. Salvando no banco de dados

Você pode usar o filtro, wp_insert_post_datagarantindo que apenas os dados $ relevantes ao seu tipo de postagem personalizado sejam retornados wp_insert_post. Certifique-se de incluir uma declaração condicional para verificar seu tipo de postagem personalizado.
API de plug-in / referência de filtro / wp insert data post «WordPress Codex

Esse gancho é chamado pela wp_insert_postfunção, chamada wp_update_post quando você atualiza seu tipo de postagem personalizado, geralmente salvando um rascunho ou publicando a postagem.

Você terá que compará-lo você mesmo, já que eu não posso falar pessoalmente sobre o significado da otimização de reduzir os dados atualizados no banco de dados.

3. Os tipos de postagem personalizados afetam o desempenho?

Na minha experiência, os tipos de postagem personalizados são uma ferramenta poderosa para gerenciar conteúdo. Não conheço outra maneira de gerenciar postagens de todas as maneiras que isso permitir, de maneira a usar menos recursos. Eu pessoalmente focaria em encontrar maneiras de reduzir o número de consultas feitas sempre que possível.

Costumava haver um problema de desempenho relacionado à estrutura do link permanente, causando um acerto quando começava com texto em vez de um número. 3 Isso foi particularmente problemático para sites que hospedam um grande número de páginas, mas foi resolvido desde a versão 3.3 do WordPress.

Estou apenas trazendo permalinks aqui porque a lesma geralmente é a primeira parte da estrutura do permalink que pode ou não ter afetado o desempenho antes da versão 3.3. Além disso, não conheço nenhum problema de desempenho resultante do uso de tipos de postagem personalizados.

Outras opções de desempenho

Transientes
Não é um substituto para manter as consultas no mínimo no seu código, mas você pode usar set_transient para armazenar as consultas por algum tempo, para que novas consultas não sejam necessárias. Aqui está o exemplo usado na postagem de Dave Clements . Além disso, observe que ele recomenda adicionar uma save_postação para excluir o transitório sempre que um determinado tipo de postagem for atualizado.

<?php // IN THE SPOTLIGHT QUERY
if( false === ( $its_query = get_transient( 'its_query' ) ) ) {
    $pttimestamp = time() + get_option('gmt_offset') * 60*60;
    $its_query = new WP_Query( array(
        'post_type' => 'spotlight',
        'posts_per_page' => 1,
            'post__not_in' => $do_not_duplicate,
        'meta_query' => array(
            array(
                'key' => '_hpc_spotlight_end_time',
                'value' => $pttimestamp,
                'compare' => '>'
            )
        )
    ) );
    set_transient( 'its_query', $its_query, 60*60*4 );
}
if( have_posts() ) { // HIDE SECTION IF NO CURRENT ITS FEATURE ?>
    // LOOP GOES HERE: NOT IMPORTANT TO EXAMPLE
<?php } ?>

Mais otimização de consultas
Thomas Griffin tem algumas boas dicas em seu tutorial Optimize WordPress Queries . Aqui está uma breve lista de sugestões:

  • Defina 'cache_results' => falseem consultas pontuais se o servidor não estiver usando o cache persistente, como o Memcached. As consultas pontuais são descritas como "consultas usadas para mostrar pequenas quantidades de dados. Pode ser que você queira apenas exibir títulos de post vinculados relacionados à postagem atual ou exibir uma lista suspensa de postagens para selecionar para uma configuração de opção específica ".

    O exemplo dele: $query = get_posts( array( 'posts_per_page' => 1, 'cache_results' => false ) );

  • Defina 'no_found_rows' => trueonde a paginação não é necessária. Isso "ignorará o MySQL contando os resultados para ver se precisamos de paginação ou não".

    O exemplo dele: $query = new WP_Query( array( 'posts_per_page' => 1, 'no_found_rows' => true ) );

  • Consulta para IDs pós somente se isso é tudo que você precisa 'fields' => 'ids' no get_posts. Isso deve reduzir significativamente a quantidade de dados retornados, o que é bastante por postagem, se você olhar para Descrição do banco de dados «WordPress Codex

    O exemplo dele: $query = get_posts( array( 'posts_per_page' => 1, 'fields' => 'ids' ) );

Além dessa última dica, o mesmo raciocínio pode ser aplicado quando você precisar apenas de um ou alguns campos de postagem usando get_post_field .

É essencial ter um sólido entendimento de como a consulta funciona. Quanto mais específico você for com suas consultas, menos trabalho exigirá do banco de dados SQL. Isso significa que há um grande número de possibilidades para gerenciar consultas ao banco de dados. Tenha cuidado com as consultas personalizadas até onde elas são executadas (é uma página de administrador?), Use a higienização adequada nas consultas diretas e tente usar as funções nativas do WordPress, onde isso permite obter o mesmo desempenho.

iyrin
fonte
2
Resposta excelente e extremamente útil, obrigado!
Jeremiah Prummer
O tema é totalmente personalizado, por isso estamos literalmente consultando apenas os itens absolutamente essenciais. Estes são extremamente úteis embora. Diante disso, vou voltar e fazer algumas alterações nas minhas consultas. ;)
Jeremiah Prummer
1
Devo acrescentar que você deve evitar meta consultas sempre que possível. Certamente, não execute uma consulta em dois meta-campos simultaneamente. Isso resulta em consultas duplas e triplas que rapidamente se tornam um problema de desempenho. Tipos de postagem personalizados geralmente podem ajudar com isso.
Charles Jaimet 9/02/16
3

Eu também adiciono:

    'no_found_rows'          => true,
    'update_post_term_cache' => false,
    'update_post_meta_cache' => false,
    'cache_results'          => false
  • no_found_rows (boolean) - torne-o verdadeiro quando você não precisa de paginação e não precisa da contagem para o número total de postagens encontradas.
  • cache_results (boolean) - publica o cache de informações.
  • update_post_meta_cache (booleano) - publica o cache de informações meta.
  • update_post_term_cache (booleano) - Publicar cache de informações do termo.

Usando esses parâmetros e passando valores como FALSE, podemos acelerar a consulta, interrompendo a execução de algumas consultas extras ao banco de dados.

Nota: Não devemos usar esses parâmetros sempre, pois adicionar coisas ao cache é a coisa certa a fazer, no entanto, eles podem ser úteis em circunstâncias específicas e você deve considerar o uso quando souber o que está fazendo.

Visite: https://drujoopress.wordpress.com/2013/06/27/how-to-optimize-wordpress-query-to-get-results-faster/#more-184

rigosan
fonte
1
Por favor edite sua resposta , e adicionar uma explicação: por que isso poderia resolver o problema?
Fuxia
Eu não posso adicionar o meu comentário sobre esta resposta: wordpress.stackexchange.com/a/166699/57674
rigosan
1

Como todo tipo de pergunta para otimização prematura, essa não pode ser respondida sem conhecer os padrões de uso exatos que muitas vezes são descobertos apenas quando você entra no ar.

Em geral, por especificações do MYSQL, não deve haver nenhum problema com a quantidade de dados. É claro que pesquisar dados mesmo com os melhores algoritmos será mais lento do que com tabelas muito menores, mas a solução para isso é uma CPU simples e mais forte.

Você pode otimizar como os metadados são armazenados (por exemplo, para não armazenar dados relacionados ao ping), mas esse tipo de coisa depende exatamente do que você faz e, no final, você ainda pode precisar de uma CPU mais forte, por isso pode não valer a pena. .

Mark Kaplun
fonte