简体   繁体   中英

MySQL Optimizing Simple Join Query - Memory or I/O Issue?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM