1. Legen Sie die Abfrage fest, bevor WP_Query ausgeführt wird
Dies scheint das Wichtigste zu sein, das Sie beachten sollten, wenn Sie versuchen, Datenbankabfragen auf ein Minimum zu beschränken, da die Abfrage nur geändert werden kann, bevor sie in der SQL-Datenbank ausgeführt wird.
Normale Abfragen
Für eine normale Abfrage verwendet WordPress die wp()
Funktion, die wiederum aufruft $wp->main( $query_vars )
. Die "is_-Variablen" aus bedingten Tags werden vor der Übergabe festgelegt WP_Query->get_posts()
, wodurch sie in eine MySQL-Datenbankabfrage konvertiert und schließlich im $ wp_query-Objekt gespeichert werden. Es ist möglich, die Abfrage zu filtern, bevor sie tatsächlich in der SQL-Datenbank ausgeführt wird .
Die pre_get_posts
Aktion greift in diesen Prozess ein und ermöglicht es Ihnen, die Abfrage zu ändern, bevor sie an übergeben wird WP_Query->get_posts()
.
Wenn Sie beispielsweise die Abfrage nach Beiträgen in der Kategorie "Hervorgehoben" filtern möchten, verwenden Sie add_action( 'pre_get_posts', 'your_function_name' );
das in_category
bedingte Tag und schließen es in dieses ein 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' );
Siehe Plugin-API / Aktionsreferenz / Vorabrufen von Beiträgen «WordPress Codex
Seite Requests
Was Seitenvorlagen, wie die Archivseite für die „vorgestellten “ -Kategorie, bedingte Tags werden nicht funktionieren , aus dem pre_get_posts
Filter. Sie können beispielsweise nicht is_category
zum Überprüfen der Archivseite verwenden, da WP_Query nicht ausgeführt wurde.
Stattdessen müssten Sie die Hauptabfrage für Seitenanfragen mit einer ändern, die ungefähr new WP_Query
so aussieht $query = new WP_Query( 'cat=123' );
. Dadurch wird die Abfrage von Anfang an mit dem entsprechenden Argument ausgeführt.
Siehe Klassenreferenz / WP-Abfrage «WordPress-Codex
2. In der Datenbank speichern
Sie können den Filter verwenden, um wp_insert_post_data
sicherzustellen, dass nur die für Ihren benutzerdefinierten Beitragstyp relevanten $ -Daten an zurückgegeben werden wp_insert_post
. Stellen Sie sicher, dass Sie eine bedingte Anweisung einschließen, um Ihren benutzerdefinierten Beitragstyp zu überprüfen.
Plugin API / Filter Reference / WP Post-Daten einfügen «WordPress Codex
Dieser Hook wird von der wp_insert_post
Funktion aufgerufen, die von wp_update_post aufgerufen wird, wenn Sie Ihren benutzerdefinierten Beitragstyp aktualisieren, normalerweise durch Speichern eines Entwurfs oder Veröffentlichen des Beitrags.
Sie müssen es jedoch selbst bewerten, da ich nicht persönlich über die Optimierungsbedeutung der Reduzierung der in der Datenbank aktualisierten Daten sprechen kann.
3. Beeinträchtigen benutzerdefinierte Beitragstypen die Leistung?
Nach meiner Erfahrung sind benutzerdefinierte Beitragstypen ein leistungsstarkes Tool für die Verwaltung von Inhalten. Ich kenne keine andere Möglichkeit, Beiträge so zu verwalten, dass weniger Ressourcen verbraucht werden. Ich würde mich persönlich darauf konzentrieren, Wege zu finden, um die Anzahl der gestellten Anfragen zu verringern, wo immer dies möglich ist.
Früher gab es ein Leistungsproblem im Zusammenhang mit der Permalink-Struktur, das einen Treffer verursachte, wenn mit Text anstelle einer Zahl begonnen wurde. 3 Dies war besonders für Websites mit einer großen Anzahl von Seiten problematisch, wurde jedoch seit WordPress Version 3.3 behoben.
Ich rufe hier nur Permalinks auf, weil der Slug normalerweise der erste Teil der Permalink-Struktur ist, der die Leistung vor Version 3.3 möglicherweise beeinträchtigt hat oder nicht. Abgesehen davon sind mir keine Leistungsprobleme bekannt, die sich aus der Verwendung benutzerdefinierter Beitragstypen ergeben.
Andere Leistungsoptionen
Transienten
Dies ist kein Ersatz, um Abfragen in Ihrem Code auf ein Minimum zu beschränken. Sie können jedoch set_transient verwenden , um die Abfragen für einige Zeit zu speichern, sodass keine neuen Abfragen erforderlich sind. Hier ist das Beispiel, das in Dave Clements 'Post verwendet wird . Beachten Sie auch, dass er empfiehlt, eine save_post
Aktion hinzuzufügen , um den Übergang jedes Mal zu löschen, wenn ein bestimmter Beitragstyp aktualisiert wird.
<?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 } ?>
Weitere Optimierung von Abfragen
Thomas Griffin hat einige gute Tipps in seinem Tutorial zur Optimierung von WordPress-Abfragen . Hier ist eine kurze Liste seiner Vorschläge:
In 'cache_results' => false
einmaligen Abfragen festlegen, wenn Ihr Server kein persistentes Caching wie Memcached verwendet. Einmalige Abfragen werden als "Abfragen" bezeichnet, die zum Anzeigen kleiner Datenmengen verwendet werden. Möglicherweise möchten Sie nur verknüpfte Beitragstitel für den aktuellen Beitrag anzeigen, oder Sie möchten eine Dropdown-Liste der Beiträge anzeigen, für die Sie auswählen können eine bestimmte Optionseinstellung. "
Sein Beispiel: $query = get_posts( array( 'posts_per_page' => 1,
'cache_results' => false ) );
Stellen Sie ein, 'no_found_rows' => true
wo keine Paginierung erforderlich ist. Dadurch wird "MySQL umgangen, indem die Ergebnisse gezählt werden, um festzustellen, ob eine Paginierung erforderlich ist oder nicht".
Sein Beispiel: $query = new WP_Query( array( 'posts_per_page' => 1,
'no_found_rows' => true ) );
Abfrage für Post - IDs nur , wenn dies alles , was Sie brauchen 'fields' => 'ids'
in get_posts
. Dies sollte die Menge der zurückgegebenen Daten erheblich reduzieren, was pro Post ziemlich viel ist, wenn man sich die
Datenbankbeschreibung «WordPress Codex» ansieht
Sein Beispiel: $query = get_posts( array( 'posts_per_page' => 1,
'fields' => 'ids' ) );
Zusätzlich zu diesem letzten Tipp kann dieselbe Argumentation angewendet werden, wenn Sie mit get_post_field nur ein oder mehrere Post-Felder benötigen .
Ein solides Verständnis der Funktionsweise der Abfrage ist von wesentlicher Bedeutung. Je genauer Sie mit Ihren Abfragen umgehen können, desto weniger Arbeit wird von Ihrer SQL-Datenbank verlangt. Dies bedeutet, dass es eine Vielzahl von Möglichkeiten gibt, Datenbankabfragen zu verwalten. Seien Sie vorsichtig mit benutzerdefinierten Abfragen, sofern diese ausgeführt werden (handelt es sich um eine Administrationsseite?), Verwenden Sie bei direkten Abfragen die ordnungsgemäße Bereinigung und versuchen Sie, native WordPress-Funktionen zu verwenden, mit denen Sie die gleiche Leistung erzielen.