wake-up-neo.net

WP_Query - filtern oder direkt?

Die Anzahl meiner Dateien, Vorlagen, Skripte, Abfragen usw. wird immer größer, und ich benötige ein gutes System, um alles zu verwalten.

Ich habe versucht, alles in Ordnung zu halten:

  • Keine <script> Tags in Vorlagen
  • Inline CSS nur, wenn es sich um eine PHP-Variable handelt, die über die Administratoroptionen dynamisch geändert werden kann
  • Einzelne große Dateien mit JS und CSS, um Anforderungen usw. Zu minimieren

Jetzt ist es an der Zeit, meine Abfragen zu organisieren, da ich mindestens zehn habe und es weiter steigt.

  1. Erste Option: Verwenden Sie für jede Abfrage die benutzerdefinierte Funktion add_filter()

    • Ich muss nicht nach Abfragen suchen, da sich alle in einer Datei oder einem Verzeichnis befinden
    • Wenn ich es ändern muss, muss ich es nur an einer Stelle ändern, nicht in all meinen verschiedenen Vorlagen
  2. Zweite Option: Schreiben Sie alle Abfragen in Templates wie gewohnt

    • Grundsätzlich ist jeder Punkt im Gegenteil zur ersten Option

Frage:

Hat die Verwendung von Filtern für Abfrageargumente Nachteile? Performance? Etwas anderes?


Beispiel:

  1. Üblich:

    $args = array(
    
            'post_type'         => 'my-post',
            'posts_per_page'    => 8,
            'orderby'           => 'Rand', 
        );
    
    }
    
    $results = new WP_Query( $args );
    
  2. Filter:

    //In one file -> easy to find and change
    add_filter( 'some_args', 'some_search_args' );
    
    function some_search_args( $search_args ) {
    
        $search_args['post_type'] = 'property';
        $search_args['posts_per_page'] = 8;
        $search_args['orderby'] = 'Rand';
    
        //All kinds of logic and conditional code to here
    
        return $search_args;
    }
    
    
    //And
    
    
    //Just include like this to any template you want and as many as you want
    //To change the query, you'll just have to change to code above
    $search_args = array();
    $search_args = apply_filters( 'some_args', $search_args );
    
    $results = new WP_Query( $search_args );
    
4
N00b

Sie müssen hier einige Dinge berücksichtigen, und es scheint, als ob Sie die Leistung einer Abfrage steigern möchten. Die erste und wichtigste Frage, die Sie sich stellen müssen, ist:

Benötige ich eine benutzerdefinierte Abfrage?

Ich habe vor einiger Zeit einen ausführlichen Post zu diesem Thema verfasst, den Sie sich ansehen sollten. Wenn Sie die obige Frage mit Ja beantwortet haben, nachdem Sie meinen Beitrag im Link gelesen haben, müssen Sie Folgendes berücksichtigen, wenn Sie benutzerdefinierte Abfragen erstellen

  • Vermeiden Sie (wo Sie können) komplexe orderby-Operationen wie das Sortieren nach Metawerten. SQL kann nicht am besten bestellen und PHP ist manchmal schneller. Ich bevorzuge usort() für komplexe Bestellungen, um Ressourcen zu sparen. Die zufällige Bestellung ist auch sehr ressourcenschonend

  • Vermeiden Sie (wo Sie können) das Erstellen komplexer Abfragen mit stark verschachtelten Meta- und Steuerabfragen, insbesondere mit vielen OR-Operatoren. Das ist ziemlich schwierig für die Ressourcen.

  • Vermeiden Sie (wo Sie können) die Verwendung von LIKE-Operatoren in Ihrem generierten SQL. Diese sind auch teuer

  • Verwenden Sie transients (und Caches), um teure Abfragen zu speichern. Bei zufälligen Abfragen ist dies nicht möglich. Sie müssen sich daher mit anderen Methoden befassen, um dieses Problem zu beheben

  • Vermeiden Sie immer die typische foreachname__-Schleife, in der Sie eine Liste von Begriffen abrufen und dann für jeden Begriff eine benutzerdefinierte Abfrage ausführen, da diese sehr teuer sind. Fragen Sie lieber alle Beiträge und einmal ab und sortieren Sie dann die Ergebnisse mit usort()

  • Erstellen Sie eine Abfrage entsprechend Ihren Anforderungen. Die meiste Zeit müssen wir nur Posts abfragen, damit ihre IDs an eine andere Funktion übergeben werden. Fragen Sie in solchen Fällen nur die Post-IDs ab. Das spart wirklich viel Ressourcen. Fügen Sie einfach 'fields'=>'ids', zu Ihren Abfrageargumenten hinzu

  • Um nicht paginierte Abfragen zu beschleunigen, verwenden Sie get_posts() oder übergeben Sie einfach 'no_found_rows'=>true an WP_Query (genau das tun `get_posts). Dies überspringt den Paginierungsprozess und spart viel Ressourcen bei großen Datenbanken

Dies ist nur als Richtlinie gedacht, um die Abfrage zu beschleunigen. Es gibt noch einige andere Dinge, um Abfragen zu beschleunigen.

Hat die Verwendung von Filtern für Abfrageargumente Nachteile? Performance? Etwas anderes?

Ich kann nicht verstehen, warum es Probleme geben könnte. Wenn Sie ein kommerzielles Thema erstellen, ist dies definitiv richtig. Etwas filterbar zu machen, erleichtert das Leben von Autoren von Kinderthemen erheblich. Es kostet vielleicht ein Milli von einer Milli von einer Millisekunde, aber es wird definitiv gut gebraucht. Es ist wie Hygiene. Sanitation kostet Zeit und Ressourcen (obwohl es sehr, sehr wenig ist), aber wenn Sie eine Millisekunde mehr für etwas ausgeben, kann Ihre Site vor Hacking und Zerstörung geschützt werden

IMHO müssten Sie nach anderen Möglichkeiten suchen, um eine Abfrage zu beschleunigen und die Benutzerfreundlichkeit und Wartbarkeit nicht zu beeinträchtigen. Option 2 ist definitiv etwas, das Sie für kommerzielle Themen tun sollten

IDEE (Könnte etwas über Bord gehen ;-))

Sie können auch pre_get_posts verwenden, um Ihre benutzerdefinierte Abfrage zu filtern und sie filterbar zu machen. Es ist so einfach wie das Festlegen eines eigenen benutzerdefinierten Parameters in Ihrer Abfrage, und dieser Parameter wird zur Ausrichtung Ihrer Abfrage verwendet

Im folgenden Beispiel verwenden wir einen benutzerdefinierten Parameter query_no, der numerische Werte enthält

Die Abfragen

$q1 = new WP_Query( ['query_no' => 1] );    
$q2 = new WP_Query( ['query_no' => 2] );    
$q3 = new WP_Query( ['query_no' => 3] );    

pre_get_posts

add_action( 'pre_get_posts', function( $q ) 
{
    if ( $q->get( 'query_no' ) == 1 ) {
        $q->set( 'posts_per_page', -1 );
        // Add any other extra arguments to set
    }

    if ( $q->get( 'query_no' ) == 2 ) {
        $q->set( 'post_type', ['post', 'page'] );
        // Add any other extra arguments to set
    }

    if ( $q->get( 'query_no' ) == 3 ) {
        $q->set( 'post_status', 'trash' );
        // Add any other extra arguments to set
    }
} );

Der Benutzer kann nun zusätzliche Argumente hinzufügen oder das übergebene ändern

add_action( 'pre_get_posts', function( $q ) 
{
    if ( $q->get( 'query_no' ) == 2 ) {
        // Lets add another post type
        $post_types = $q->get( 'post_type' );
        $post_types = array_merge( $post_types, ['my_post_type'] );

        $q->set( 'post_type'     , $post_types );
        $q->set( 'posts_per_page', -1          );
        // Add any other extra arguments to set
    }

}, 
11 // Make sure this runs after the default action
); 
4
Pieter Goosen