Ich habe eine Abfrage, die etwa 90 Sekunden dauert, obwohl die Tabellen die richtigen Indizes haben sollten. Ich verstehe nicht warum.Single INNER JOIN von zwei gut indizierten Tabellen dauert mehr als eine Minute
Ich benutze MySQL und die Tabellen sind InnoDB.
Dies ist die Abfrage:
SELECT count(*)
FROM `following_lists` fl INNER JOIN users u
ON fl.user_uuid = u.user_uuid
WHERE fl.following_query_id = 1000010 AND u.status <= 2
Ich erwarte, dass diese Abfrage auf dem Tisch starten following_lists
, die WHERE-Bedingung greift etwa 4K Datensätze als pro, diese Datensätze in die Tabelle users
durch ihren Primärschlüssel, Scheck beitreten der Wert eines Felds in der Benutzertabelle und gibt die Anzahl der resultierenden Datensätze zurück. Warum dauert es so lange? Könnte es sein, weil die beiden Felder, denen ich die Tabellen beifüge, CHAR (40) sind und keine ganzen Zahlen?
Dies sind die beteiligten Tabellen und deren Indizes:
CREATE TABLE `users` (
`user_uuid` CHAR(40) NOT NULL,
`status` TINYINT UNSIGNED NOT NULL,
...
PRIMARY KEY (`user_uuid`),
...
)
CREATE TABLE `following_lists` (
`following_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`following_query_id` INT UNSIGNED NOT NULL,
`user_uuid` CHAR(40) NOT NULL,
PRIMARY KEY (`following_id`),
KEY `query_id` (`following_query_id`),
KEY `user_uuid` (`user_uuid`)
)
Und das ist der Ausgang der erklären Abfrage:
+----+-------------+-------+--------+--------------------+----------+---------+--------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+--------------------+----------+---------+--------------+------+-------------+
| 1 | SIMPLE | fl | ref | query_id,user_uuid | query_id | 4 | const | 3718 | |
| 1 | SIMPLE | u | eq_ref | PRIMARY | PRIMARY | 160 | fl.user_uuid | 1 | Using index |
+----+-------------+-------+--------+--------------------+----------+---------+--------------+------+-------------+
Weitere Informationen:
Die Tabelle
following_lists
hat ungefähr 25k Reihen, aber nur 3718 habenfl.following_query_id = 1000010
.Die Tabelle
users
hat etwa 160.000 Zeilen, aber nur 3718 sollte in der Verknüpfung ausgewählt werden. Nur 40 Datensätze erfüllen beide Bedingungenfl.following_query_id = 1000010 AND u.status <= 2
. Die Abfrage ist langsam, selbst wenn ich die BedingungAND u.status <= 2
entferne.
wäre ich nicht überrascht, wenn es das CHAR (40) ist. Bei einem ganzzahligen Wert wird 1 Vergleich benötigt; mit diesem CHAR (40) werden bis zu 40 Vergleiche benötigt. Wie viele tatsächlich benötigt werden, hängt von den tatsächlichen Werten in deinem CHAR ab (40), wenn die Werte alle die ersten X Zeichen gleich haben, wird es mindestens so viele nehmen. Wenn ich mich nicht irre, decken die CHAR-Indizes von MySQL auch nicht die gesamte Zeichenfolge ab, sondern nur eine bestimmte Anzahl von führenden Zeichen. – Uueerdo
Verwenden beide Spalten dieselbe Sortierung und denselben Zeichensatz? –
Siehe die akzeptierte Antwort auf diese andere SO Frage. Es könnte Ihnen Hinweise geben, wie Sie die Leistung mit UUID verbessern können. https://StackOverflow.com/questions/2365132/uuid-performance-in-mysql/2365176 –