I am trying to figure out why a query in our production environment is taking so much time (~20 sec)
. I have tried creating the database locally and generated the same data and am getting under half a second run time with the exact same queries.
Would anyone know what could cause such a slowdown? My best guess right now is a possible memory limitation that causes the index being used to swap to disk
See tables and Explain the query below:
(.15 sec) SELECT COUNT(*) FROM user;
(.32 sec) SELECT COUNT(*) FROM profile;
(20.80 sec) SELECT COUNT(*) FROM user INNER JOIN profile ON user.id = profile.user_id;
user table:
| id | guid | status | username | email |
user index:
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| user | 0 | PRIMARY | 1 | id | A | 355448 | NULL | NULL | | BTREE | | |
| user | 0 | unique_email | 1 | email | A | 2 | NULL | NULL | YES | BTREE | | |
| user | 0 | unique_username | 1 | username | A | 2 | NULL | NULL | YES | BTREE | | |
profile table:
| user_id | firstname | lastname | full_name |
profile index:
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------+------------+-----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| profile | 0 | PRIMARY | 1 | user_id | A | 330496 | NULL | NULL | | BTREE | | |
| profile | 1 | idx_profile_full_name | 1 | full_name | A | 2 | NULL | NULL | YES | BTREE | | |
+---------+------------+-----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
EXPLAIN of query:
mysql> EXPLAIN SELECT COUNT(*) FROM profile JOIN user ON user.id = profile.user_id;
+----+-------------+---------+--------+---------------+-----------------------+---------+------------------------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+--------+---------------+-----------------------+---------+------------------------+--------+-------------+
| 1 | SIMPLE | profile | index | PRIMARY | idx_profile_full_name | 258 | NULL | 330496 | Using index |
| 1 | SIMPLE | user | eq_ref | PRIMARY | PRIMARY | 4 | humhub.profile.user_id | 1 | Using index |
+----+-------------+---------+--------+---------------+-----------------------+---------+------------------------+--------+-------------+
Most likely a MySQL 5.7/8.0 query planner sudden-brain-death heisenbug. Run ANALYZE TABLE user; ANALYZE TABLE profile;
ANALYZE TABLE user; ANALYZE TABLE profile;
and see if the query planner gets un-confused.
The only way to avoid recurrence is to use an index hint:
SELECT COUNT(*) FROM profile USE INDEX (PRIMARY) JOIN user ON user.id = profile.user_id;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.