MySQL根据WHERE加入不一致的性能

时间:2011-11-02 18:42:10

标签: mysql join inner-join

对于某些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秒才能完成。我的查询是否需要重写或索引是否有问题?

0 个答案:

没有答案