Come ottimizzare il sito WP per milioni di post


19

Sto lavorando su un sito Web per un'azienda che molto probabilmente creerà milioni di post tramite un tipo di post personalizzato. Sono preghiere, quindi sostanzialmente l'utente del front-end invia una breve frase tramite un modulo. Tutto ciò che interessa alla società è il contenuto del post e la data di pubblicazione. Il sito non è ancora stato ancora lanciato e hanno già oltre 120.000 post, quindi sono davvero serio quando dico milioni.

Quindi, un paio di domande sull'ottimizzazione:

  1. Diciamo che ho una categoria "in primo piano" in un tipo di post personalizzato che ha 500.000 post. La categoria in evidenza ha solo 500 post. Se creo una query per i post in primo piano, sto interrogando tutti i 500.000 post o solo i 500 in primo piano? Cosa succede se desidero solo visualizzare i dieci post più recenti in primo piano?
  2. Quando si salva questo tipo di post personalizzato nel database, ci sono alcune cose che posso fare per ridurre le risorse del server, soprattutto perché l'unica cosa veramente necessaria è il contenuto del post e la data?
  3. Dovrei anche usare un tipo di post personalizzato? Mi piace in linea di principio perché è ben integrato nell'amministratore di WordPress, ma se ci sono svantaggi significativi nelle prestazioni, suppongo di poter fare qualcosa di diverso.

Non ho mai lavorato su un progetto su questa scala, quindi sono un po 'più preoccupato per le prestazioni del solito. Grazie per qualsiasi aiuto!


È importante ridurre al minimo le query del database nelle funzioni di WordPress e chiamare gli script in modo appropriato, ma gran parte dell'ottimizzazione ha a che fare con l'impostazione e la configurazione del server. Per questo, cerca nella rete Server Fault. serverfault.com/search?q=optimize+wordpress
iyrin,

@RyanLoremIpsum - grazie per il commento, ma speravo di rispondere per le mie domande specifiche. La maggior parte di ciò che ho trovato riguarda il server stesso, non il modo in cui WordPress funziona e come ottimizzarlo dal punto di vista del codice
Jeremiah Prummer,

Risposte:


26

1. Impostare la query prima dell'esecuzione di WP_Query

Questa sembra essere la cosa più importante da tenere a mente quando si cerca di ridurre al minimo le query del database poiché l'unica possibilità di modificare la query è, ovviamente, prima che venga eseguita nel database SQL.

Query normali
Per una query normale, WordPress utilizza la wp()funzione, che a sua volta chiama $wp->main( $query_vars ). Le "variabili is_" dai tag condizionali vengono impostate prima di passarle a WP_Query->get_posts(), che le converte in una query del database MySQL e infine le memorizza nell'oggetto $ wp_query. È possibile filtrare la query prima che venga effettivamente eseguita nel database SQL .

L' pre_get_postsazione si aggancia a questo processo, consentendo di modificare la query prima che venga passata WP_Query->get_posts().

Ad esempio, se si desidera filtrare la query per i post nella categoria "in primo piano", è necessario utilizzare add_action( 'pre_get_posts', 'your_function_name' );e includere il in_categorytag condizionale all'interno 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' );

Vedi API Plugin / Riferimenti azione / pre get post «Codice WordPress

Richieste
di pagina Come per i modelli di pagina, come la pagina di archivio per la categoria "in primo piano", i tag condizionali non funzioneranno dal pre_get_postsfiltro. Ad esempio, non è possibile utilizzare is_categoryper verificare la pagina di archivio perché WP_Query non è stato eseguito.

Invece, dovresti modificare la query principale per le richieste di pagina con una new WP_Querysimile $query = new WP_Query( 'cat=123' );. Ciò esegue la query con l'argomento appropriato impostato dall'inizio.

Vedi riferimento classe / query WP «Codice WordPress

2. Salvataggio nel database

Puoi utilizzare il filtro wp_insert_post_dataassicurandoti di restituire solo i $ dati pertinenti al tuo tipo di post personalizzato wp_insert_post. Assicurati di includere un'istruzione condizionale per verificare il tuo tipo di post personalizzato.
API plug-in / Filtro di riferimento / wp inserisci dati post «Codice WordPress

Questo hook viene chiamato dalla wp_insert_postfunzione, che viene chiamata da wp_update_post quando aggiorni il tipo di post personalizzato, in genere salvando una bozza o pubblicando il post.

Dovrai confrontarlo da solo, dato che non posso parlare personalmente dell'importanza dell'ottimizzazione della riduzione dei dati aggiornati nel database.

3. I tipi di post personalizzati influiscono sulle prestazioni?

Nella mia esperienza, i tipi di post personalizzati sono un potente strumento per la gestione dei contenuti. Non conosco nessun altro modo per gestire i post in tutti i modi che consente in modo da utilizzare meno risorse. Mi concentrerei personalmente sulla ricerca di modi per ridurre il numero di query fatte, ove possibile.

In passato si verificava un problema di prestazioni relativo alla struttura del permalink che causava un hit quando inizia con il testo anziché un numero. 3 Ciò è stato particolarmente problematico per i siti che ospitano un gran numero di pagine, ma è stato risolto dalla versione 3.3 di WordPress.

Sto solo facendo apparire i permalink qui perché la lumaca è di solito la prima parte della struttura del permalink che può avere o meno influire sulle prestazioni prima della versione 3.3. A parte questo, non sono a conoscenza di problemi di prestazioni derivanti dall'uso di tipi di post personalizzati.

Altre opzioni di prestazione

Transitori
Questo non è un rimpiazzo per mantenere le query al minimo nel tuo codice, ma puoi usare set_transient per memorizzare le query per un po 'di tempo in modo che non siano necessarie nuove query. Ecco l'esempio usato nel post di Dave Clements . Inoltre, tieni presente che consiglia di aggiungere save_postun'azione per eliminare il transitorio ogni volta che viene aggiornato un determinato tipo di post.

<?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 } ?>

Maggiore ottimizzazione delle query
Thomas Griffin ha alcuni buoni consigli nel suo tutorial Ottimizza le query di WordPress . Ecco un breve elenco dei suoi suggerimenti:

  • Impostato 'cache_results' => falsein query una tantum se il server non utilizza la memorizzazione nella cache persistente come Memcached. Le query una tantum sono descritte come "query utilizzate per mostrare piccole quantità di dati. È possibile che tu voglia solo visualizzare i titoli dei post collegati relativi al post corrente oppure potresti visualizzare un menu a discesa dei post da selezionare per un'impostazione di opzione particolare ".

    Il suo esempio: $query = get_posts( array( 'posts_per_page' => 1, 'cache_results' => false ) );

  • Impostare 'no_found_rows' => truedove l'impaginazione non è necessaria. Questo "ignorerà MySQL contando i risultati per vedere se abbiamo bisogno di impaginazione o meno".

    Il suo esempio: $query = new WP_Query( array( 'posts_per_page' => 1, 'no_found_rows' => true ) );

  • Query per gli ID pubblicare solo se questo è tutto ciò che serve 'fields' => 'ids' in get_posts. Ciò dovrebbe ridurre in modo significativo la quantità di dati restituiti, che è abbastanza per post se si guarda alla descrizione del database «Codice WordPress

    Il suo esempio: $query = get_posts( array( 'posts_per_page' => 1, 'fields' => 'ids' ) );

Oltre a quest'ultimo suggerimento, lo stesso ragionamento può essere applicato quando sono necessari solo uno o alcuni campi di posta utilizzando get_post_field .

È essenziale avere una solida conoscenza di come funziona la query. Quanto più specifico puoi essere con le tue query, tanto meno lavoro ti richiederà dal tuo database SQL. Ciò significa che esistono numerose possibilità per la gestione delle query del database. Prestare attenzione alle query personalizzate per quanto riguarda la loro esecuzione (è una pagina di amministrazione?), Utilizzare la sanitizzazione corretta nelle query dirette e provare a utilizzare le funzioni native di WordPress in cui consente di ottenere le stesse prestazioni.


2
Risposta eccellente ed estremamente utile, grazie!
Jeremiah Prummer,

Il tema è interamente personalizzato, quindi stiamo letteralmente interrogando solo gli elementi assolutamente essenziali. Questi sono estremamente utili però. Detto questo, tornerò indietro e apporterò alcune modifiche alle mie domande. ;)
Jeremiah Prummer,

1
Vorrei aggiungere che dovresti evitare le meta query dove possibile. Certamente non eseguire una query su due meta-campi contemporaneamente. Ciò si traduce in query doppie e triple che diventano rapidamente un fattore negativo per le prestazioni. I tipi di post personalizzati possono spesso aiutare in questo.
Charles Jaimet,

3

Aggiungo anche:

    'no_found_rows'          => true,
    'update_post_term_cache' => false,
    'update_post_meta_cache' => false,
    'cache_results'          => false
  • no_found_rows (booleano): rendilo vero quando non hai bisogno di alcuna impaginazione e non hai bisogno del conteggio per il numero totale di post trovati.
  • cache_results (booleano) - Pubblica cache di informazioni.
  • update_post_meta_cache (booleano) - Pubblica cache delle informazioni meta.
  • update_post_term_cache (booleano): cache di informazioni post termine.

Usando questi parametri e passando valori come FALSE, possiamo rendere più veloce la query interrompendo l'esecuzione di alcune query aggiuntive sul database.

Nota: non dovremmo sempre usare questi parametri poiché l'aggiunta di elementi alla cache è la cosa giusta da fare, tuttavia questi possono essere utili in circostanze specifiche e dovresti prendere in considerazione l'utilizzo quando sai cosa stai facendo.

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


1
Si prega di modificare la risposta , e aggiungere una spiegazione: perché potrebbe che risolvere il problema?
fuxia

Non posso aggiungere il mio commento a questa risposta: wordpress.stackexchange.com/a/166699/57674
rigosan

1

Come tutti i tipi di domande di ottimizzazione prematura, a questa domanda non si può davvero rispondere senza conoscere i modelli di utilizzo esatti che troppe volte vengono scoperti solo quando si va in diretta.

In generale, secondo le specifiche MYSQL non dovrebbe esserci alcun problema con la quantità di dati. Naturalmente la ricerca di dati anche con i migliori algoritmi sarà più lenta rispetto a tabelle molto più piccole, ma la soluzione è CPU semplice e più potente.

Potresti voler ottimizzare il modo in cui sono archiviati i metadati (ad esempio per non archiviare i dati relativi al ping), ma questo tipo di cose dipende da cosa fai esattamente e alla fine potresti avere ancora bisogno di CPU più potenti, quindi potrebbe non valere la pena .

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.