【问题标题】:mysql primary key returning less results than compound composite indexmysql主键返回的结果少于复合复合索引
【发布时间】:2012-02-22 04:16:47
【问题描述】:

我继承了一个存在一些设计问题的数据库架构

请注意,桌子上还有另外 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 索引,为什么该查询不使用?

【问题讨论】:

    标签: mysql


    【解决方案1】:

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

    你有两个选择:

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

    【讨论】:

    • 运行分析表后,我得到的数字略有不同,但其粗略值相同。我担心的是,对于更复杂的查询,它只使用主索引。
    • 如果 userid 设置为自动递增,userid_2 键应该是唯一的吗?
    猜你喜欢
    • 2019-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-05
    • 1970-01-01
    • 2022-11-21
    • 1970-01-01
    相关资源
    最近更新 更多