为什么mysql不使用我的索引?

时间:2011-03-22 17:22:13

标签: mysql subquery

我有两张桌子:


mysql> desc myps3t_gameusertrophyinfo;

+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| id        | int(11)      | NO   | PRI | NULL    | auto_increment |
| user_id   | int(11)      | NO   | MUL | NULL    |                |
| trophy_id | int(11)      | NO   | MUL | NULL    |                |
| date      | datetime     | NO   | MUL | NULL    |                |
| date_read | varchar(100) | NO   |     | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+
5 rows in set (0.19 sec)


mysql> show index from myps3t_gameusertrophyinfo;

+---------------------------+------------+------------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table                     | Non_unique | Key_name                           | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+---------------------------+------------+------------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| myps3t_gameusertrophyinfo |          0 | PRIMARY                            |            1 | id          | A         |     4004589 |     NULL | NULL   |      | BTREE      |         |
| myps3t_gameusertrophyinfo |          0 | user_id                            |            1 | user_id     | A         |        7686 |     NULL | NULL   |      | BTREE      |         |
| myps3t_gameusertrophyinfo |          0 | user_id                            |            2 | trophy_id   | A         |     4004589 |     NULL | NULL   |      | BTREE      |         |
| myps3t_gameusertrophyinfo |          1 | myps3t_gameusertrophyinfo_403f60f  |            1 | user_id     | A         |        7686 |     NULL | NULL   |      | BTREE      |         |
| myps3t_gameusertrophyinfo |          1 | myps3t_gameusertrophyinfo_61a683d8 |            1 | trophy_id   | A         |       22624 |     NULL | NULL   |      | BTREE      |         |
| myps3t_gameusertrophyinfo |          1 | idx_gameusertrophyinfo_date        |            1 | date        | A         |     4004589 |     NULL | NULL   |      | BTREE      |         |
+---------------------------+------------+------------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
7 rows in set (0.06 sec)

另一张桌子:



mysql> desc myps3t_gametrophyinfo ;
+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| id        | int(11)      | NO   | PRI | NULL    | auto_increment |
| game_id   | int(11)      | NO   | MUL | NULL    |                |
| name      | varchar(500) | NO   |     | NULL    |                |
| desc      | varchar(500) | NO   |     | NULL    |                |
| type      | varchar(20)  | NO   |     | NULL    |                |
| pic_url   | varchar(200) | NO   |     | NULL    |                |
| desc_pt   | varchar(500) | NO   |     | NULL    |                |
| name_pt   | varchar(500) | NO   |     | NULL    |                |
| hidden_id | int(11)      | NO   |     | NULL    |                |
| total_id  | int(11)      | NO   |     | NULL    |                |
| trophy_id | int(11)      | NO   |     | NULL    |                |
| addon_id  | int(11)      | YES  |     | NULL    |                |
| points    | double       | NO   |     | 0       |                |
| sony_id   | int(11)      | YES  |     | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+
14 rows in set (0.00 sec)

mysql> show index from myps3t_gametrophyinfo;
+-----------------------+------------+-------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table                 | Non_unique | Key_name                      | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-----------------------+------------+-------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| myps3t_gametrophyinfo |          0 | PRIMARY                       |            1 | id          | A         |       25976 |     NULL | NULL   |      | BTREE      |         |
| myps3t_gametrophyinfo |          1 | myps3t_gametrophyinfo_game_id |            1 | game_id     | A         |         764 |     NULL | NULL   |      | BTREE      |         |
+-----------------------+------------+-------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+

当我执行此查询时:



mysql> explain select * from myps3t_gameusertrophyinfo a, myps3t_gametrophyinfo b  where a.trophy_id = b.id and b.addon_id = 58;                                        +----+-------------+-------+--------+--------------------------------------------------------------+---------+---------+-----------------------------+---------+-------------+
| id | select_type | table | type   | possible_keys                                                | key     | key_len | ref                         | rows    | Extra       |
+----+-------------+-------+--------+--------------------------------------------------------------+---------+---------+-----------------------------+---------+-------------+
|  1 | SIMPLE      | a     | ALL    | myps3t_gameusertrophyinfo_61a683d8,myps3t_gameusertrophyinfo | NULL    | NULL    | NULL                        | 4004592 |             |
|  1 | SIMPLE      | b     | eq_ref | PRIMARY                                                      | PRIMARY | 4       | fabriciols_ps3t.a.trophy_id |       1 | Using where |
+----+-------------+-------+--------+--------------------------------------------------------------+---------+---------+-----------------------------+---------+-------------+
2 rows in set (0.00 sec)

为什么mysql不使用我的密钥? 这个查询需要超过30秒,第一个表有4milion记录...

- 编辑 -

for quasnoi



mysql> SELECT COUNT(*), COUNT(DISTINCT addon_id), SUM(addon_id = 58) FROM myps3t_gametrophyinfo;
+----------+--------------------------+--------------------+
| COUNT(*) | COUNT(DISTINCT addon_id) | SUM(addon_id = 58) |
+----------+--------------------------+--------------------+
|    25976 |                      160 |                  6 |
+----------+--------------------------+--------------------+
1 row in set (0.00 sec)

3 个答案:

答案 0 :(得分:2)

MySQL选择a作为主要表格,b作为驱动表格。它确实在PRIMARY KEY上使用b进行连接。

myps3t_gametrophyinfo (addon_id)上创建索引,这样b更有可能被选为主要表格。

答案 1 :(得分:0)

你可以尝试

select * from 
myps3t_gametrophyinfo b 
STRAIGHT_JOIN myps3t_gameusertrophyinfo a ON (a.trophy_id = b.id) 
WHERE b.addon_id = 58;

答案 2 :(得分:0)

我可能会重写查询以尝试获得更合理的执行路径。我觉得下面这样的东西更有可能让你获得你想要的表现,并且更明确你对人类读者所做的事情

SELECT * FROM myps3t_gametrophyinfo a LEFT JOIN myps3t_gameusertrophyinfo b ON a.id = b.trophy_id WHERE a.addon_id=58;