Wie erweitere ich WP_Query, um eine benutzerdefinierte Tabelle in die Abfrage aufzunehmen?

31

Ich habe Tage über dieses Problem jetzt gewesen. Anfänglich ging es darum, wie die Follower-Daten eines Benutzers in einer Datenbank gespeichert werden, für die ich hier bei WordPress Answers einige nette Empfehlungen erhalten habe. Nach den Empfehlungen habe ich eine neue Tabelle wie diese hinzugefügt:

id  leader_id   follower_id
1   2           4
2   3           10
3   2           10

In der obigen Tabelle hat die erste Zeile einen Benutzer mit einer ID von 2, auf den ein Benutzer mit einer ID von 4 folgt. In der zweiten Zeile folgt einem Benutzer mit einer ID von 3 ein Benutzer mit einer ID Dieselbe Logik gilt für die dritte Reihe.

Jetzt möchte ich im Wesentlichen WP_Query erweitern, sodass ich nur die von den Vorgesetzten eines Benutzers abgerufenen Posts auf die von beschränken kann. Wenn ich also unter Berücksichtigung der obigen Tabelle die Benutzer-ID 10 an WP_Query übergebe, sollten die Ergebnisse nur Posts nach Benutzer-ID 2 und Benutzer-ID 3 enthalten.

Ich habe viel gesucht, um eine Antwort zu finden. Ich habe auch kein Tutorial gesehen, das mir helfen soll, die WP_Query-Klasse zu erweitern. Ich habe Mike Schinkels Antworten (Erweiterung von WP_Query) auf ähnliche Fragen gesehen, aber ich habe wirklich nicht verstanden, wie ich sie auf meine Bedürfnisse anwenden kann. Es wäre toll, wenn mir jemand dabei helfen könnte.

Links zu Mikes Antworten wie gewünscht: Link 1 , Link 2

John
quelle
Fügen Sie bitte einen Link zu Mikes Antworten hinzu.
Kaiser
1
Kannst du ein Beispiel geben, wonach du fragen würdest? WP_Querydient dazu, Beiträge zu erhalten, und ich verstehe nicht, wie dies mit Beiträgen zusammenhängt.
Mor7ifer
@kaiser Ich habe die Frage mit Links zu Mikes Antworten aktualisiert.
John
@ m0r7if3r »Ich möchte WP_Query so erweitern, dass ich das Abrufen von Posts auf das von nur den Leadern eines Benutzers beschränken kann«, also ähnlich wie "Beiträge nach Autor abrufen".
Kaiser
2
@ m0r7if3r Posts ist genau das, wonach ich fragen muss. Die abzurufenden Posts sollten jedoch von Benutzern stammen, die als Anführer eines bestimmten Benutzers in der benutzerdefinierten Tabelle aufgeführt sind. Mit anderen Worten, ich möchte WP_Query mitteilen, dass alle Beiträge aller Benutzer abgerufen werden sollen, die als Anführer eines Benutzers mit der ID '10' in der benutzerdefinierten Tabelle aufgeführt sind.
John

Antworten:

13

Wichtiger Hinweis: Der richtige Weg, dies zu tun, besteht NICHT darin, Ihre Tabellenstruktur zu ändern, sondern wp_usermeta zu verwenden. Dann müssen Sie kein benutzerdefiniertes SQL erstellen, um Ihre Posts abzufragen (obwohl Sie immer noch benutzerdefiniertes SQL benötigen, um eine Liste aller Benutzer zu erhalten, die einem bestimmten Supervisor Bericht erstatten - beispielsweise im Abschnitt "Admin"). Da das OP jedoch nach dem Schreiben von benutzerdefiniertem SQL gefragt hat, wird im Folgenden die derzeit empfohlene Vorgehensweise zum Injizieren von benutzerdefiniertem SQL in eine vorhandene WordPress-Abfrage beschrieben.

Wenn Sie komplexe Verknüpfungen ausführen, können Sie nicht einfach den Filter posts_where verwenden, da Sie die Verknüpfung, die Auswahl und möglicherweise auch die Gruppierung nach oder die Reihenfolge nach Abschnitten der Abfrage ändern müssen.

Verwenden Sie am besten den Filter "posts_clauses". Dies ist ein äußerst nützlicher Filter (der nicht missbraucht werden sollte!), Mit dem Sie die verschiedenen Teile der SQL-Anweisung anhängen / ändern können, die von den vielen Codezeilen in WordPress Core automatisch generiert werden. Die Filterrückrufsignatur lautet: function posts_clauses_filter_cb( $clauses, $query_object ){ }und erwartet, dass Sie zurückkehren $clauses.

Die Klauseln

$clausesist ein Array, das die folgenden Schlüssel enthält; Jeder Schlüssel ist eine SQL-Zeichenfolge, die direkt in der endgültigen SQL-Anweisung verwendet wird, die an die Datenbank gesendet wird:

  • woher
  • gruppiere nach
  • Beitreten
  • Sortieren nach
  • deutlich
  • Felder
  • Grenzen

Wenn Sie eine Tabelle in der Datenbank sind hinzugefügt (dies nur tun , wenn Sie absolut nicht Hebel post_meta, user_meta oder Taxonomien) Sie wahrscheinlich mehr als eine dieser Klauseln zum Beispiel die brauchen, zu berühren fields(die „SELECT“ Teil der SQL - Anweisung), die join(alle Ihre Tabellen, außer der in Ihrer "FROM" - Klausel) und möglicherweise die orderby.

Änderung der Klauseln

Am besten referenzieren Sie dazu den relevanten Schlüssel aus dem $clausesArray, das Sie vom Filter erhalten haben:

$join = &$clauses['join'];

Wenn Sie jetzt $joinÄnderungen $clauses['join']vornehmen , werden Sie diese direkt ändern , sodass die Änderungen $clausesbei der Rückgabe übernommen werden.

Erhalt der ursprünglichen Klauseln

Wahrscheinlich möchten Sie (im Ernst, hören Sie zu) das vorhandene SQL, das WordPress für Sie generiert hat, beibehalten. Wenn nicht, sollten Sie sich posts_requeststattdessen wahrscheinlich den Filter ansehen - das ist die vollständige mySQL-Abfrage, kurz bevor sie an die Datenbank gesendet wird. Warum willst du das tun? Sie wahrscheinlich nicht.

Um die vorhandene SQL in den Klauseln beizubehalten, müssen Sie daran denken, an die Klauseln anzuhängen und sie nicht zuzuweisen (dh: Verwenden Sie $join .= ' {NEW SQL STUFF}';nicht $join = '{CLOBBER SQL STUFF}';. Beachten Sie, dass jedes Element des $clausesArrays eine Zeichenfolge ist, wenn Sie daran anhängen möchten. Sie werden wahrscheinlich ein Leerzeichen vor anderen Zeichen-Token einfügen wollen, andernfalls werden Sie wahrscheinlich einen SQL-Syntaxfehler erzeugen.

Sie können einfach davon ausgehen, dass in jeder Klausel immer etwas enthalten ist, und denken Sie daher daran, jede neue Zeichenfolge mit einem Leerzeichen wie in: $join .= ' my_tablezu beginnen.

$join = &$clauses['join'];
if (! empty( $join ) ) $join .= ' ';
$join .= "JOIN my_table... "; // <-- note the space at the end
$join .= "JOIN my_other_table... ";


return $clauses;

Das ist mehr als alles andere eine stilistische Sache. Das Wichtigste, an das Sie sich erinnern sollten, ist: Lassen Sie immer ein Leerzeichen VOR Ihrer Zeichenfolge, wenn Sie an eine Klausel anhängen, in der bereits SQL enthalten ist!

Etwas zusammensetzen

Die erste Regel bei der Entwicklung von WordPress ist, so viele Kernfunktionen wie möglich zu verwenden. Dies ist der beste Weg, um Ihre Arbeit zukunftssicher zu machen. Angenommen, das Kernteam entscheidet, dass WordPress jetzt SQLite oder Oracle oder eine andere Datenbanksprache verwendet. Jedes handgeschriebene mySQL kann ungültig werden und Ihr Plugin oder Theme beschädigen! Es ist besser, WP so viel SQL wie möglich selbst generieren zu lassen und nur die benötigten Bits hinzuzufügen.

Die erste Geschäftsaufgabe besteht also WP_Querydarin, so viel wie möglich von Ihrer Basisabfrage zu generieren. Die genaue Methode, mit der wir dies tun, hängt weitgehend davon ab, wo diese Liste der Beiträge erscheinen soll. Wenn es sich um einen Unterabschnitt der Seite handelt (nicht um Ihre Hauptabfrage), würden Sie verwenden get_posts(). Wenn es sich um die Hauptabfrage handelt, können Sie sie vermutlich verwenden query_posts()und damit fertig werden. Die richtige Methode besteht jedoch darin, die Hauptabfrage abzufangen, bevor sie die Datenbank erreicht (und Serverzyklen beansprucht). Verwenden Sie daher den requestFilter.

Okay, Sie haben Ihre Abfrage generiert und die SQL wird erstellt. Tatsächlich wurde es erstellt, aber nicht an die Datenbank gesendet. Mit dem posts_clausesFilter fügen Sie Ihre Mitarbeiterbeziehungstabelle in den Mix ein. Nennen wir diese Tabelle {$ wpdb-> Präfix}. 'user_relationship' und es ist eine Kreuzungstabelle. (Übrigens empfehle ich, diese Tabellenstruktur zu generieren und in eine richtige Schnittstellentabelle mit den folgenden Feldern umzuwandeln: 'relationship_id', 'user_id', 'related_user_id', 'relationship_type'; dies ist viel flexibler und leistungsfähiger. .. Aber ich schweife ab).

Wenn ich verstehe, was Sie tun möchten, möchten Sie die ID eines Anführers übergeben und dann nur die Beiträge der Anhänger dieses Anführers anzeigen. Ich hoffe, ich habe das richtig verstanden. Wenn es nicht stimmt, müssen Sie das, was ich sage, nehmen und an Ihre Bedürfnisse anpassen. Ich bleibe bei deiner Tischstruktur: Wir haben ein leader_idund ein follower_id. Daher ist JOIN {$wpdb->posts}.post_authorals Fremdschlüssel für die 'follower_id' in Ihrer 'user_relationship'-Tabelle aktiviert.

add_filter( 'posts_clauses', 'filter_by_leader_id', 10, 2 ); // we need the 2 because we want to get all the arguments

function filter_by_leader_id( $clauses, $query_object ){
  // I don't know how you intend to pass the leader_id, so let's just assume it's a global
  global $leader_id;

  // In this example I only want to affect a query on the home page.
  // This is where the $query_object is used, to help us avoid affecting
  // ALL queries (since ALL queries pass through this filter)
  if ( $query_object->is_home() ){
    // Now, let's add your table into the SQL
    $join = &$clauses['join'];
    if (! empty( $join ) ) $join .= ' '; // add a space only if we have to (for bonus marks!)
    $join .= "JOIN {$wpdb->prefix}employee_relationship EMP_R ON EMP_R.follower_id = {$wpdb->posts}.author_id";

    // And make sure we add it to our selection criteria
    $where = &$clauses['where'];
    // Regardless, you always start with AND, because there's always a '1=1' statement as the first statement of the WHERE clause that's added in by WP/
    // Just don't forget the leading space!
    $where .= " AND EMP_R.leader_id={$leader_id}"; // assuming $leader_id is always (int)

    // And I assume you'll want the posts "grouped" by user id, so let's modify the groupby clause
    $groupby = &$clauses['groupby'];
    // We need to prepend, so...
    if (! empty( $groupby ) ) $groupby = ' ' . $groupby; // For the show-offs
    $groupby = "{$wpdb->posts}.post_author" . $groupby;
  }

  // Regardless, we need to return our clauses...
  return $clauses;
}
Tom Auger
quelle
13

Ich beantworte diese Frage sehr spät und entschuldige mich dafür. Ich war viel zu sehr mit Fristen beschäftigt, um mich darum zu kümmern.

Ein großes Dankeschön an @ m0r7if3r und @kaiser für die Bereitstellung der Basislösungen, die ich erweitern und in meine Anwendung implementieren konnte. Diese Antwort enthält Details zu meiner Anpassung der von @ m0r7if3r und @kaiser angebotenen Lösungen.

Lassen Sie mich zunächst erklären, warum diese Frage überhaupt gestellt wurde. Aus der Frage und den Kommentaren könnte man ersehen, dass ich versuche, WP_Query dazu zu bringen, Beiträge aller Benutzer (Leiter) abzurufen, denen ein bestimmter Benutzer (Anhänger) folgt. Die Beziehung zwischen dem Follower und dem Leader wird in einer benutzerdefinierten Tabelle gespeichert follow. Die häufigste Lösung für dieses Problem besteht darin, die Benutzer-IDs aller Leiter eines Followers aus der Folgetabelle zu ziehen und in einem Array abzulegen. Siehe unten:

global $wpdb;
$results = $wpdb->get_results($wpdb->prepare('SELECT leader_id FROM cs_follow WHERE follower_id = %s', $user_id));

foreach($results as $result)
    $leaders[] = $result->leader_id;

Sobald Sie das Array von Führungskräften haben, können Sie es als Argument an WP_Query übergeben. Siehe unten:

if (isset($leaders)) $authors = implode(',', $leaders); // Necessary as authors argument of WP_Query only accepts string containing post author ID's seperated by commas

$args = array(
    'post_type'         => 'post',
    'posts_per_page'    => 10,
    'author'            => $authors
);

$wp_query = new WP_Query( $args );

// Normal WordPress loop continues

Die obige Lösung ist der einfachste Weg, um die gewünschten Ergebnisse zu erzielen. Es ist jedoch nicht skalierbar. In dem Moment, in dem Sie einen Follower haben, der Zehntausenden von Führern folgt, wird das resultierende Array von Führer-IDs extrem groß und zwingt Ihre WordPress-Site, 100 MB - 250 MB Speicher bei jedem Laden der Seite zu belegen und die Site schließlich zum Absturz zu bringen. Die Lösung des Problems besteht darin, eine SQL-Abfrage direkt in der Datenbank auszuführen und relevante Posts abzurufen. Zu diesem Zeitpunkt kam die Lösung von @ m0r7if3r zur Rettung. Auf Empfehlung von @ kaiser habe ich mich vorgenommen, beide Implementierungen zu testen. Ich habe ungefähr 47.000 Benutzer aus einer CSV-Datei importiert, um sie für eine neue Testinstallation von WordPress zu registrieren. Die Installation lief unter dem Thema Twenty Eleven. Anschließend habe ich eine for-Schleife ausgeführt, damit etwa 50 Benutzer jedem anderen Benutzer folgen. Der Unterschied in der Abfragezeit für die Lösung von @kaiser und @ m0r7if3r war atemberaubend. Die Lösung von @ kaiser benötigte normalerweise ca. 2 bis 5 Sekunden für jede Abfrage. Die von mir angenommene Variation tritt auf, wenn WordPress Abfragen für die spätere Verwendung zwischenspeichert. Andererseits zeigte die Lösung von @ m0r7if3r eine durchschnittliche Abfragezeit von 0,02 ms. Zum Testen beider Lösungen hatte ich die Indizierung für die Spalte leader_id auf ON gesetzt. Ohne Indexierung stieg die Abfragezeit drastisch an.

Die Speichernutzung bei Verwendung einer Array-basierten Lösung lag zwischen 100 und 150 MB und ging bei Ausführung von Direct SQL auf 20 MB zurück.

Ich habe mit der Lösung von @ m0r7if3r einen Fehler gemacht, als ich die Follower-ID an die Filterfunktion posts_where übergeben musste. Zumindest erlaubt WordPress meines Wissens keine Möglichkeit, eine Variable an Filer-Funktionen zu übergeben. Sie können zwar globale Variablen verwenden, aber ich wollte globale Variablen vermeiden. Am Ende habe ich WP_Query erweitert, um das Problem endlich zu beheben. Hier ist die endgültige Lösung, die ich implementiert habe (basierend auf der Lösung von @ m0r7if3r).

class WP_Query_Posts_by_Leader extends WP_Query {
    var $follower_id;

    function __construct($args=array()) {
        if(!empty($args['follower_id'])) {
            $this->follower_id = $args['follower_id'];
            add_filter('posts_where', array($this, 'posts_where'));
        }

        parent::query($args);
    }

    function posts_where($where) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'follow';
        $where .= $wpdb->prepare(" AND post_author IN (SELECT leader_id FROM " . $table_name . " WHERE follower_id = %d )", $this->follower_id);
        return $where;
    }
}


$args = array(
    'post_type'         => 'post',
    'posts_per_page'    => 10,
    'follower_id'       => $follower_id
);

$wp_query = new WP_Query_Posts_by_Leader( $args );

Hinweis: Ich habe die obige Lösung schließlich mit 1,2 Millionen Einträgen in der folgenden Tabelle ausprobiert. Die durchschnittliche Abfragezeit lag bei 0,060 ms.

John
quelle
3
Ich habe dir nie gesagt, wie sehr ich die Diskussion über diese Frage schätze. Nun , da ich herausgefunden habe , dass ich es verpasst haben , habe ich eine upvote hinzufügen :)
kaiser
8

Sie können dies mit einer vollständigen SQL-Lösung unter Verwendung des posts_whereFilters tun . Hier ist ein Beispiel dafür:

if( some condition ) 
    add_filter( 'posts_where', 'wpse50305_leader_where' );
    // lol, question id is the same forward and backward

function wpse50305_leader_where( $where ) {
    $where .= $GLOBALS['wpdb']->prepare( ' AND post_author '.
        'IN ( '.
            'SELECT leader_id '.
            'FROM custom_table_name '.
            'WHERE follower_id = %s'.
        ' ) ', $follower_id );
    return $where;
}

Ich denke, dass es einen Weg gibt, dies auch zu tun JOIN, aber ich kann nicht darauf kommen. Ich werde weiter damit spielen und die Antwort aktualisieren, wenn ich sie bekomme.

Alternativ können Sie es, wie von @kaiser vorgeschlagen, in zwei Teile aufteilen: Abrufen der Leiter und Ausführen der Abfrage. Ich habe das Gefühl, dass dies weniger effizient ist, aber es ist sicherlich der verständlichere Weg. Sie müssten die Effizienz selbst testen, um festzustellen, welche Methode besser ist, da verschachtelte SQL-Abfragen sehr langsam werden können.

AUS DEN KOMMENTAREN:

Sie sollten die Funktion in Ihre einfügen functions.phpund das add_filter()Richtige tun, bevor die query()Methode von WP_Queryaufgerufen wird. Im Anschluss daran sollten Sie sicherstellen remove_filter(), dass die anderen Abfragen davon nicht betroffen sind.

mor7ifer
quelle
1
A bearbeitet und hinzugefügt prepare(). Hoffe du hast nichts gegen die Bearbeitung. Und ja: Leistung muss am OP gemessen werden. Sowieso: Ich denke immer noch, das sollte einfach usermeta sein und sonst nichts.
Kaiser
@ m0r7if3r Danke, dass du eine Lösung ausprobiert hast. Ich habe gerade einen Kommentar als Antwort auf Kaisers Antwort gepostet, mit Bedenken hinsichtlich möglicher Skalierbarkeitsprobleme. Bitte berücksichtigen Sie dies.
John
1
@ Kaiser nicht im geringsten dagegen, in der Tat schätze ich es eher :)
mor7ifer
@ m0r7if3r Danke. Mit Jungs wie Sie in Community Rocks :)
Kaiser
1
Sie sollten die Funktion in Ihre einfügen functions.phpund das add_filter()Richtige tun, bevor die query()Methode von WP_Queryaufgerufen wird. Im Anschluss daran sollten Sie sicherstellen remove_filter(), dass die anderen Abfragen davon nicht betroffen sind. Ich bin mir nicht sicher, wie das Problem mit dem Umschreiben von posts_where
URLs aussehen
6

Vorlagen-Tag

Platzieren Sie einfach beide Funktionen in Ihrer functions.phpDatei. Passen Sie dann die 1. Funktion an und fügen Sie Ihren benutzerdefinierten Tabellennamen hinzu. Dann benötigen Sie einen Versuch / Fehler, um die aktuelle Benutzer-ID innerhalb des resultierenden Arrays zu entfernen (siehe Kommentar).

/**
 * Get "Leaders" of the current user
 * @param int $user_id The current users ID
 * @return array $query The leaders
 */
function wpse50305_get_leaders( $user_id )
{
    global $wpdb;

    return $wpdb->query( $wpdb->prepare(
        "
            SELECT `leader_id`, `follower_id`
            FROM %s
                WHERE `follower_id` = %s
            ORDERBY `leader_id` ASC
        ",
        // Edit the table name
        "{$wpdb->prefix}custom_table_name"
        $user_id
    ) );
}

/**
 * Get posts array that contain posts by 
 * "Leaders" the current user is following
 * @return array $posts Posts that are by the current "Leader
 */
function wpse50305_list_posts_by_leader()
{
    get_currentuserinfo();
    global $current_user;

    $user_id = $current_user->ID;

    $leaders = wpse5035_get_leaders( $user_id );
    // could be that you need to loop over the $leaders
    // and get rid of the follower ids

    return get_posts( array(
        'author' => implode( ",", $leaders )
    ) );
}

Innerhalb der Vorlage

Hier können Sie mit Ihren Ergebnissen machen, was Sie wollen.

foreach ( wpse50305_list_posts_by_leader() as $post )
{
    // do something with $post
}

HINWEIS Wir dont haben Testdaten , usw. , so dass die oben ein wenig von einem Ratespiel ist. Stellen Sie sicher, dass Sie diese Antwort mit dem, was für Sie funktioniert hat, bearbeiten, damit wir für spätere Leser ein zufriedenstellendes Ergebnis erzielen. Ich werde die Bearbeitung genehmigen, falls Sie zu wenig Wiederholungen haben. Sie können diese Notiz dann auch löschen. Vielen Dank.

Kaiser
quelle
2
JOINist viel teurer. Plus: Wie bereits erwähnt, haben wir keine Testdaten. Bitte testen Sie beide Antworten und klären Sie uns mit Ihren Ergebnissen auf.
Kaiser
1
WP_Query selbst arbeitet beim Abfragen mit JOINs zwischen Posts-Tabelle und Postmeta. Ich habe gesehen, wie die PHP-Speicherauslastung auf 70 MB - 200 MB pro Seitenladevorgang angestiegen ist. Um so etwas mit vielen gleichzeitigen Benutzern ausführen zu können, wäre eine extreme Infrastruktur erforderlich. Ich denke, da WordPress bereits eine ähnliche Technik implementiert, sollten JOINs weniger anstrengend sein als die Arbeit mit einem Array von IDs.
John
1
@ John gut zu hören. Ich möchte wirklich wissen, was auf mich zukommt.
Kaiser
4
Ok hier sind die Testergebnisse. Zu diesem Zweck habe ich ungefähr 47.000 Benutzer aus einer CSV-Datei hinzugefügt. Später wurde eine for-Schleife ausgeführt, damit die ersten 45 Benutzer jedem anderen Benutzer folgen. Dies führte dazu, dass 3.704.951 Datensätze in meiner benutzerdefinierten Tabelle gespeichert wurden. Anfänglich gab mir die Lösung von @ m0r7if3r eine Abfragezeit von 95 Sekunden, die nach dem Einschalten der Indizierung für die Spalte leader_id auf 0,020 ms sank. Der gesamte verwendete PHP-Speicher betrug ca. 20 MB. Auf der anderen Seite hat Ihre Lösung bei eingeschalteter Indizierung ca. 2 bis 5 Sekunden für die Abfrage benötigt. Der gesamte verbrauchte PHP-Speicher lag bei 117MB.
John
1
Ich füge eine andere Antwort (wir verarbeiten können und ändern / bearbeiten auf dem) als Code - Formatierung in den Kommentaren einfach saugt: P
kaiser
3

Hinweis: Diese Antwort hier soll eine ausführliche Diskussion in den Kommentaren vermeiden

  1. Hier ist der OPs-Code aus den Kommentaren, um die erste Gruppe von Testbenutzern hinzuzufügen. Ich muss zu einem realen Beispiel modifiziert werden.

    for ( $j = 2; $j <= 52; $j++ ) 
    {
        for ( $i = ($j + 1); $i <= 47000; $i++ )
        {
            $rows_affected = $wpdb->insert( $table_name, array( 'leader_id' => $i, 'follower_id' => $j ) );
        }
    }

    OP About Test Hierfür habe ich ungefähr 47.000 Benutzer aus einer CSV-Datei hinzugefügt. Später wurde eine for-Schleife ausgeführt, damit die ersten 45 Benutzer jedem anderen Benutzer folgen.

    • Dies führte dazu, dass 3.704.951 Datensätze in meiner benutzerdefinierten Tabelle gespeichert wurden.
    • Anfänglich gab mir die Lösung von @ m0r7if3r eine Abfragezeit von 95 Sekunden, die nach dem Einschalten der Indizierung für die Spalte leader_id auf 0,020 ms sank. Der gesamte verwendete PHP-Speicher betrug ca. 20 MB.
    • Auf der anderen Seite hat Ihre Lösung bei eingeschalteter Indizierung ca. 2 bis 5 Sekunden für die Abfrage benötigt. Der gesamte verbrauchte PHP-Speicher lag bei 117MB.
  2. Meine Antwort auf diesen ↑ Test:

    Ein "realer" Test: Lassen Sie jeden Benutzer einem folgen $leader_amount = rand( 0, 5 );und addieren Sie dann die Anzahl $leader_amount x $random_ids = rand( 0, 47000 );zu jedem Benutzer. Bisher wissen wir: Meine Lösung wäre extrem schlecht, wenn ein Benutzer sich gegenseitig folgt. Weiter: Sie werden zeigen, wie Sie den Test durchgeführt haben und wo genau Sie die Timer hinzugefügt haben.

    Ich muss auch feststellen, dass die ↑ obige Zeiterfassung nicht wirklich gemessen werden kann, da es auch Zeit kosten würde, die Schleife zusammen zu berechnen. Besser wäre es, den resultierenden Satz von IDs in einer zweiten Schleife zu durchlaufen.

hier weiter verarbeiten

Kaiser
quelle
2
Hinweis für diejenigen, die diese Frage befolgt haben: Ich bin dabei, die Leistung unter verschiedenen Bedingungen zu messen, und werde das Ergebnis in einem oder drei Tagen veröffentlichen. Dies war aufgrund des Umfangs der erforderlichen Testdaten eine äußerst zeitaufwendige Aufgabe erzeugt.
John