C'è un modo per escludere il contenuto dalla variabile post per risparmiare sull'utilizzo della RAM?


9

Quindi, ho incontrato quello che sembra un problema di utilizzo della RAM WP e sto cercando una soluzione.

L'unico posto in cui sto realmente riscontrando questo problema sul mio sito è con una pagina Mappa del sito che sto cercando di popolare, ma una soluzione a questo problema potrebbe essere universalmente applicata e risparmiare sull'utilizzo della RAM in un intero sito.

In sostanza, questa pagina Mappa del sito che ho è un elenco di tutti postse pagessul mio sito. Gli unici elementi della variabile $ post a cui ho bisogno di accedere in questa pagina sono il titolo e il permalink. Sfortunatamente, la query che sto usando restituisce tutti i post con tutte le informazioni in ciascuna delle loro variabili $ post.

Di seguito è riportato un esempio di una query che sto utilizzando in questa pagina Mappa del sito per un singolo custom-post-type"prodotto" con una tassonomia personalizzata di "integratori" e il termine "integratori". La mia pagina Mappa del sito contiene più di tali query, ma a scopo esplicativo includo solo il codice per questa singola query.

 $varArray= array(
      'post_type' => 'products',
      'post_status' => 'publish',
      'supplements' => 'all-supplements',
      'posts_per_page' => -1,
      'orderby' => 'title',
      'order' => 'ASC'
 );
 $myProducts= new WP_Query($varArray);

La maggior parte delle informazioni salvate all'interno della variabile $ post (per il mio sito, e immagino che questa tendenza sia vista per un uso generale) si trova all'interno del "contenuto" L'utilizzo tipico della RAM per la mia pagina Mappa del sito è ~ 140 MB (segnalato dalla barra di debug), mentre l'utilizzo per qualsiasi altra pagina tipica sul mio sito è di 50-60 MB. Grande differenza. Ieri la pagina Mappa del sito ha smesso di funzionare (WSOD) e per risolverlo ho dovuto aumentare la quantità massima di RAM che WP può utilizzare. Quindi sto aumentando le risorse di sistema complessivamente necessarie a causa di una singola pagina.

Quindi, arrivo alla mia domanda.

C'è un percorso / opzione da qualche parte all'interno di Wordpress che mi manca che potrebbe recuperare posts/ pagesgradire una normale query, ma NON ottenere il contenuto per i post recuperati?

Oppure, in alternativa, c'è un modo più semplice per me di afferrare solo elementi particolari all'interno di una determinata query (Title / Permaklink / Slug / etc ...) invece di ottenere l'intera variabile $ post shebang?

Mi sembra che per molte applicazioni WP, l'unico posto in cui "il contenuto" di un post / pagina sarebbe tipicamente necessario sia su quella pageo postpagina (ovviamente ci sono eccezioni qui) e che avere accesso al contenuto completo per i post / Le pagine recuperate dalla query su altre pagine sono semplicemente eccessive. Se esiste un modo per evitare di caricare l'intero contenuto per le pagine dell'elenco dei post, è possibile salvare una quantità significativa di utilizzo della RAM.

Qualsiasi aiuto sarebbe apprezzato.

Risposte:


8

Puoi provare un trucco con l'interrogazione diretta dei dati post e l'impostazione del filtercampo degli oggetti post sampleprima di passarli get_permalink()per ridurre l'utilizzo della memoria.

Vedi il problema di utilizzo della memoria get_permalink per un ragionamento dettagliato alla base.


Questa soluzione ha funzionato alla grande. Bene, dopo una piccola rissa che è. :) Ho dovuto capire come includere la mia tassonomia / termine personalizzati nella query, ma questo è stato di grande aiuto. La pagina Mappa del sito ora utilizza 70 MB di RAM (secondo la barra di debug). Grazie per l'ottimo puntatore.
Programmatore Dan,

4

Potresti provare ad aggiungere questo al tuo array:

'nopaging' => true,
'no_found_rows' => true,
'update_post_meta_cache' => false,
'update_post_term_cache' => false

Sembra piuttosto autoesplicativo, ma essenzialmente non stai interrogando tutte le variabili post e solo le cose di cui hai bisogno.


2

Programmatore Dan, mah amico!

Iniziamo SELECTcon query personalizzate utilizzando il $wpdbglobale. Il Codex ha un'ottima voce sulla visualizzazione dei post utilizzando una query di selezione personalizzata . Se lo usi setup_postdata()puoi scorrere i risultati come se fossi seduto nel ciclo standard di Wordpress:

global $wpdb;

$sitemap_query = "
    SELECT $wpdb->posts.ID, $wpdb->posts.post_title, $wpdb->posts.guid
    FROM $wpdb->posts
    WHERE $wpdb->posts.post_status = 'publish' 
    AND $wpdb->posts.post_type IN ('post','supplement','another_post_type')
    ORDER BY $wpdb->posts.post_type, $wpdb->posts.post_title DESC
    ";

$sitemap_nodes = $wpdb->get_results($sitemap_query, OBJECT);

if( $sitemap_nodes ):
    global $post;
    foreach ( $sitemap_nodes as $post ):
        setup_postdata( $post );
        ?>

<!-- //Use standard Wordpress template tags for SELECT'd data within The Loop here -->
    <?php the_title() ?>
    <?php the_permalink() ?>

        <?php
    endforeach;
endif;

Questa query estrae solo ID, titoli e GUID dei post (usati per determinare il permalink di un post) ignorando assolutamente tutto il resto. Inoltre ordina prima i risultati prima di post_typeallora post_title, anche se potresti voler utilizzare più query per separare i tuoi tipi di post (teoricamente con un piccolo successo).

Ovviamente potresti voler saltare sull'uso setup_postdata()e semplicemente passare in rassegna $sitemap_nodes, o giocherellare con la query per ottenere i risultati di cui hai bisogno.

Se si chiama setup_postdata()e si attiva la modalità di debug, è probabile che le chiamate spargano avvisi a destra e sinistra riguardanti (deliberatamente) le informazioni mancanti. Potresti voler lanciare una @chiamata prima della funzione per eliminarle dopo aver verificato che la tua query personalizzata funziona correttamente.

Ma questo dovrebbe iniziare! È possibile fare riferimento al seguente diagramma del database (dalla pagina Descrizione del database sul Codex) per individuare i campi che è necessario interrogare:

Diagramma del database di Wordpress

MODIFICARE:

La soluzione più efficiente in termini di memoria è probabilmente quella che combina una SELECTquery personalizzata con il protip di @ Rarst :)


1

WP_Query ha un parametro "campi restituiti" che assomiglia a questo:

$args = array(
 'fields' => 'ids'
);
$query = new WP_Query( $args );

Se utilizzato in questo modo, WP_Query restituisce solo gli ID post, non l'intero oggetto post. Poi si può semplicemente utilizzare i get_permalink(), get_the_title()e altre funzioni assortiti WordPress per recuperare i tuoi contenuti in base all'ID palo.


1
Si noti che le funzioni che accettano l'ID del post di solito vengono eseguite immediatamente get_post()su di esso per recuperare i dati completi e quindi annullare completamente lo scopo del recupero degli ID da soli.
Rarst

1
Buono a sapersi! Avevo l'impressione di essere intelligente.
Dalton,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.