Zapytanie:Optymalizacja długo kwerenda w mysql w ogromną wielkość stołu 33m wierszy
SELECT users.id as uid, name, avatar, avatar_date, driver, messages.id AS mid,messages.msg, messages.removed, messages.from_anonym_id, messages.t
o_anonym_id, (messages.date DIV 1000) AS date, from_id = 162077 as outbox, !(0 in (SELECT read_state FROM messages as msgs
WHERE (msgs.from_id = messages.from_id or msgs.from_id = messages.user_id) and msgs.user_id = 162077 and removed = 0)) as read_state
FROM dialog, messages, users
WHERE messages.id = dialog.mid and ((uid1 = 162077 and users.id = uid2) or (uid2 = 162077 and users.id = uid1))
ORDER BY dialog.mid DESC LIMIT 0, 101;
Stoły struktura:
mysql> desc messages;
+----------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| from_id | int(11) | NO | MUL | NULL | |
| user_id | int(11) | NO | MUL | NULL | |
| group_id | int(11) | NO | | NULL | |
| to_number | varchar(30) | NO | MUL | NULL | |
| msg | text | NO | | NULL | |
| image | varchar(20) | NO | | NULL | |
| date | bigint(20) | NO | | NULL | |
| read_state | tinyint(1) | NO | | 0 | |
| removed | tinyint(1) | NO | MUL | NULL | |
| from_anonym_id | int(10) unsigned | NO | MUL | NULL | |
| to_anonym_id | int(10) unsigned | NO | MUL | NULL | |
+----------------+------------------+------+-----+---------+----------------+
mysql> desc dialog;
+----------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| uid1 | int(11) | NO | MUL | NULL | |
| uid2 | int(11) | NO | MUL | NULL | |
| mid | int(11) | NO | MUL | NULL | |
| from_anonym_id | int(10) unsigned | NO | MUL | NULL | |
| to_anonym_id | int(10) unsigned | NO | MUL | NULL | |
+----------------+------------------+------+-----+---------+----------------+
mysql> show index from messages;
+----------+------------+----------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+----------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| messages | 0 | PRIMARY | 1 | id | A | 42944290 | NULL | NULL | | BTREE | | |
| messages | 1 | user_id_2 | 1 | user_id | A | 2147214 | NULL | NULL | | BTREE | | |
| messages | 1 | user_id_2 | 2 | read_state | A | 2862952 | NULL | NULL | | BTREE | | |
| messages | 1 | user_id_2 | 3 | removed | A | 2862952 | NULL | NULL | | BTREE | | |
| messages | 1 | from_id | 1 | from_id | A | 825851 | NULL | NULL | | BTREE | | |
| messages | 1 | from_id | 2 | to_number | A | 825851 | NULL | NULL | | BTREE | | |
| messages | 1 | to_number | 1 | to_number | A | 29 | NULL | NULL | | BTREE | | |
| messages | 1 | idx_user_id | 1 | user_id | A | 2044966 | NULL | NULL | | BTREE | | |
| messages | 1 | idx_from_id | 1 | from_id | A | 447336 | NULL | NULL | | BTREE | | |
| messages | 1 | removed | 1 | removed | A | 29 | NULL | NULL | | BTREE | | |
| messages | 1 | from_anonym_id | 1 | from_anonym_id | A | 29 | NULL | NULL | | BTREE | | |
| messages | 1 | to_anonym_id | 1 | to_anonym_id | A | 29 | NULL | NULL | | BTREE | | |
+----------+------------+----------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
12 rows in set (0.01 sec)
mysql> show index from dialog;
+--------+------------+----------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------+------------+----------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| dialog | 0 | PRIMARY | 1 | id | A | 6378161 | NULL | NULL | | BTREE | | |
| dialog | 1 | uid1 | 1 | uid1 | A | 455582 | NULL | NULL | | BTREE | | |
| dialog | 1 | uid1 | 2 | uid2 | A | 6378161 | NULL | NULL | | BTREE | | |
| dialog | 1 | uid2 | 1 | uid2 | A | 2126053 | NULL | NULL | | BTREE | | |
| dialog | 1 | idx_mid | 1 | mid | A | 6378161 | NULL | NULL | | BTREE | | |
| dialog | 1 | from_anonym_id | 1 | from_anonym_id | A | 17 | NULL | NULL | | BTREE | | |
| dialog | 1 | to_anonym_id | 1 | to_anonym_id | A | 17 | NULL | NULL | | BTREE | | |
+--------+------------+----------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
PS proszę nie doradza mi żadnego przepisu tylko teoretyczne, praktyczne przykłady. Thx z góry.
Jeśli usunąć to stwierdzenie
!(0 in (SELECT read_state FROM messages as msgs
WHERE (msgs.from_id = messages.from_id or msgs.from_id = messages.user_id) and msgs.user_id = 162077 and removed = 0)) as read_state
kwerenda działa bardzo dobrze w porównaniu do oryginału: 101 wierszy w zestawie (0,04 sek)
przypuszczam to jest główny problem, ale muszę to tam pole. Może być ktoś, kto może zmienić tę rundę i uczynić ją szybszą, byłby bardzo zadowolony.
Jak szybko działa samo zapytanie, bez usuniętej instrukcji? – kevin628
Może się różnić w zależności od współczynnika obciążenia, ale teraz '101 rzędów w zestawie (5,59 s)' Jeśli system jest spokojny - 2-3 sekundy, co z pewnością stanowi problem. –
Jeśli tabela 'messages' zawiera tabelę zawierającą 33 miliony rekordów, to zapytanie wewnętrzne - to, które usunięto w celu poprawy wydajności - wykonuje skanowanie tabeli 33 milionów rekordów dla każdego elementu w zapytaniu zewnętrznym (które jest ograniczona do 102 rekordów). Tak więc 102 * 33 miliony to DUŻO rekordów do przeskanowania. Rozważ użycie indeksów klucza złożonego, jeśli to możliwe. Jeśli nie, możesz rozważyć ponowne przeanalizowanie sposobu powiązania danych, aby móc korzystać z indeksów kluczy złożonych. – kevin628