einen einzigen FULLTEXT- Index Verwendung:
FULLTEXT(user_email, user_firstname, user_lastname)
und die 3 Ursachen ändern man nur:
MATCH (user_email, user_firstname, user_lastname) AGAINST ('sometext')
Hier ist ein weiteres Problem: ORDER BY ... DESC LIMIT 1400, 50
. Lies über die Übel von pagination via OFFSET. Das hat einen Workaround, aber ich bezweifle, ob es für Ihre Aussage gelten würde.
Haben wirklich Tausende von Benutzern den Text? Führt jemand (außer einem Suchmaschinenroboter) wirklich 29 Seiten durch? Überlegen Sie, ob es sinnvoll ist, eine so langatmige Benutzeroberfläche zu haben.
Und eine dritte Ausgabe. Betrachten Sie "Lazy Eval". Das heißt, finden Sie zuerst die Benutzer-IDs, , dann verbinden Sie sich zurück zu users
und users_oauth
, um den Rest der Spalten zu erhalten. Es wäre eine einzige SELECT
mit der MATCH
in einer abgeleiteten Tabelle, dann JOIN
zu den beiden Tabellen. Wenn der ORDER BY
ein LIMIT
in der abgeleiteten Tabelle sein kann, könnte es ein großer Gewinn sein.
Bitte geben Sie an, zu welcher Tabelle jede Spalte gehört - mein letzter Absatz ist ungenau, weil ich nichts über die Datumsspalte weiß.
aktualisieren
In Ihrem zweiten Versuch hinzugefügt Sie OR
, die Dinge stark verlangsamt. Lassen Sie uns das in eine UNION
verwandeln, um zu versuchen, die neue Verlangsamung zu vermeiden. Lassen Sie uns zunächst die UNION
debuggen:
(SELECT * -- no mention of oauth columns
FROM users -- No JOIN
WHERE users.user_id LIKE ...
ORDER BY user_id DESC
LIMIT 0, 50
)
UNION ALL
(SELECT * -- no mention of oauth columns
FROM users
WHERE MATCH ...
ORDER BY user_id DESC
LIMIT 0, 50
)
-Test durch jedes SELECT
separat Timing. Wenn einer davon noch langsam ist, dann konzentrieren wir uns darauf. Dann testen Sie die UNION
. (Dies ist ein Fall, bei dem die Verwendung des Befehlszeilentools mysql praktischer ist als PHP.)
Durch Aufteilen kann jeder SELECT
einen optimalen Index verwenden. Die UNION
hat einige Overhead, aber möglicherweise weniger als die Ineffizienz von OR
.
Jetzt lass uns users_oauth einklappen.
Zunächst scheinen Sie eine sehr wichtige INDEX(oauth_user_id)
fehlt. Fügen Sie das hinzu!
Jetzt wollen wir sie zusammensetzen.
SELECT u.*
FROM (.... the entire union query ...) AS u
LEFT JOIN users_oauth ON users.user_id = users_oauth.oauth_user_id
ORDER BY user_id DESC -- yes, repeat
LIMIT 0, 50 -- yes, repeat
Können Sie ein EXPLAIN mit dieser Abfrage ausführen und die Ergebnisse veröffentlichen? – Besi
Und identifizieren, aus welchen Tabellen die Spalten stammen. –
Haben Sie einen Volltextindex für die Felder, nach denen gesucht wird, gefunden? Gegen ...? – Shadow