mysql主键返回的结果少于复合复合索引

时间:2012-02-22 04:16:47

标签: mysql

我继承了一个有一些设计问题的数据库模式

请注意,桌子上还有另外9个键,我没有在下面列出,有问题的键看起来像

+-------+------------+----------------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name                   | Seq_in_index | Column_name  | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| users |          0 | PRIMARY                    |            1 | userid       | A         |         604 |     NULL | NULL   |      | BTREE      |         |               |
| users |          1 | userid_2                   |            1 | userid       | A         |         604 |     NULL | NULL   |      | BTREE      |         |               |
| users |          1 | userid_2                   |            2 | age          | A         |         604 |     NULL | NULL   | YES  | BTREE      |         |               |
| users |          1 | userid_2                   |            3 | image        | A         |         604 |      255 | NULL   | YES  | BTREE      |         |               |
| users |          1 | userid_2                   |            4 | gender       | A         |         604 |     NULL | NULL   | YES  | BTREE      |         |               |
| users |          1 | userid_2                   |            5 | last_login   | A         |         604 |     NULL | NULL   | YES  | BTREE      |         |               |
| users |          1 | userid_2                   |            6 | latitude     | A         |         604 |     NULL | NULL   | YES  | BTREE      |         |               |
| users |          1 | userid_2                   |            7 | longitude    | A         |         604 |     NULL | NULL   | YES  | BTREE      |         |               |
+-------+------------+----------------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
在包含以下字段的表中。

+--------------------------------+---------------------+------+-----+-------------------+----------------+
| Field                          | Type                | Null | Key | Default           | Extra          |
+--------------------------------+---------------------+------+-----+-------------------+----------------+
| userid                         | int(11)             | NO   | PRI | NULL              | auto_increment |
| age                            | int(11)             | YES  |     | NULL              |                |
| image                          | varchar(500)        | YES  |     |                   |                |
| gender                         | varchar(10)         | YES  |     | NULL              |                |
| last_login                     | timestamp           | YES  | MUL | NULL              |                |
| latitude                       | varchar(20)         | YES  | MUL | NULL              |                |
| longitude                      | varchar(20)         | YES  |     | NULL              |                |
+--------------------------------+---------------------+------+-----+-------------------+----------------+
运行解释声明并强制使用 userid_2 ,它使用 522行

describe SELECT userid, age FROM users USE INDEX(userid_2) WHERE `userid` >=100 and age >27   limit 10 ;
+----+-------------+-------+-------+---------------+----------+---------+------+------+--------------------------+
| id | select_type | table | type  | possible_keys | key      | key_len | ref  | rows | Extra                    |
+----+-------------+-------+-------+---------------+----------+---------+------+------+--------------------------+
|  1 | SIMPLE      | users | index | userid_2      | userid_2 | 941     | NULL |  522 | Using where; Using index |
+----+-------------+-------+-------+---------------+----------+---------+------+------+--------------------------+
1 row in set (0.02 sec)

如果我不强制它使用索引,它只使用主键,它只包含用户ID,只使用 261行

mysql> describe SELECT userid, age FROM users  WHERE userid >=100 and age >27   limit 10 ;
+----+-------------+-------+-------+--------------------------------------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys                              | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+--------------------------------------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | users | range | PRIMARY,users_user_ids_key,userid,userid_2 | PRIMARY | 4       | NULL |  261 | Using where |
+----+-------------+-------+-------+--------------------------------------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)

问题

  1. 为什么在使用复合复合索引时检查更多行?
  2. 如果查询中未指定查询,为什么查询不使用userid_2索引?

1 个答案:

答案 0 :(得分:1)

该行计数仅是基于索引值分布的估计值。

您有两种选择:

  1. 执行ANALYZE TABLE mytable重新计算分布,然后重新尝试describe
  2. 不要担心不重要的事情...... rows无论如何只是估计