对于某些WHERE条件,我有一个查询需要几秒钟才能完成。据我所知,所有内容都已正确索引,但性能仍然很差。所有表都是InnoDB,blog_users和blog_users_profiles包含大约500万行,forum_contacts包含大约10K行。
查询
SELECT blog.*
FROM blog_users AS blog
INNER JOIN blog_user_profiles AS profile ON blog.user_id = profile.user_id
INNER JOIN forum_contacts AS contact ON profile.forum_id = contact.user_id
WHERE blog.comments > :comment_cutoff
AND blog.last_active > :time_cutoff
AND contact.type = :contact_type
AND contact.area = :location
LIMIT 0, 100
解释输出
+----+-------------+---------+--------+------------------------------+-----------+---------+------------------------------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+--------+------------------------------+-----------+---------+------------------------------+---------+-------------+
| 1 | SIMPLE | blog | range | PRIMARY,last_active,comments | comments | 3 | NULL | 1313813 | Using where |
| 1 | SIMPLE | profile | eq_ref | PRIMARY,forum_id | PRIMARY | 3 | xc_db.blog.user_id | 1 | |
| 1 | SIMPLE | contact | eq_ref | PRIMARY,type,area,user_id | PRIMARY | 80 | xc_db.profile.forum_id,const | 1 | Using where |
+----+-------------+---------+--------+------------------------------+-----------+---------+------------------------------+---------+-------------+
表结构(不相关的行被剪切)
blog_users
+-------------+-----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-----------------------+------+-----+---------+----------------+
| user_id | mediumint(8) unsigned | NO | PRI | NULL | auto_increment |
| username | varchar(16) | NO | UNI | NULL | |
| comments | mediumint(7) unsigned | NO | MUL | NULL | |
| last_active | int(10) unsigned | NO | MUL | NULL | |
+-------------+-----------------------+------+-----+---------+----------------+
blog_user_profiles
+----------+-----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-----------------------+------+-----+---------+-------+
| user_id | mediumint(8) unsigned | NO | PRI | NULL | |
| forum_id | mediumint(8) unsigned | NO | MUL | 0 | |
+----------+-----------------------+------+-----+---------+-------+
forum_contacts
+---------+-----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-----------------------+------+-----+---------+-------+
| user_id | mediumint(8) unsigned | NO | PRI | NULL | |
| type | varchar(25) | NO | PRI | NULL | |
| area | varchar(255) | NO | MUL | NULL | |
+---------+-----------------------+------+-----+---------+-------+
奇怪的是,执行时间似乎与返回的总行数成反比。例如,像contact.area ='United States'这样的查询返回几千行,执行时间不到0.01秒。但是,具有较少结果行的查询(例如,返回20行的contact.area ='Egypt')需要超过5秒才能完成。我的查询是否需要重写或索引是否有问题?