为什么我的 MySQL 复合索引的基数小于同一列上的单个索引?
Why my MySQL composite index has less Cardinality than a single index on the same column?
我首先在 table 中创建了 2 个单独的索引:uid 和 time。然后我决定创建一个复合索引(uid,时间)。
但是为什么复合索引(第 3 行)中 uid 的基数小于单个索引(第 1 行)中 uid 的基数?
mysql> show index from full_data;
+-----------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| full_data | 1 | uid | 1 | uid | A | 26394792 | NULL | NULL | YES | BTREE | | |
| full_data | 1 | time | 1 | time | A | 6934463 | NULL | NULL | YES | BTREE | | |
| full_data | 1 | composite | 1 | uid | A | 23166632 | NULL | NULL | YES | BTREE | | |
| full_data | 1 | composite | 2 | time | A | 86380688 | NULL | NULL | YES | BTREE | | |
+-----------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
4 rows in set (0.05 sec)
基数,在该上下文中,是基于对索引 BTree 的一些随机探测的粗略估计。 INDEX(uid)
执行一组随机探测; INDEX(uid, time)
探测不同的 BTree。
当您同时拥有 INDEX(uid)
和 INDEX(uid, time)
时,几乎没有必要保留前者。它会使磁盘混乱,增加 insert/update/delete 时间,并且不会显着加快 SELECT
。它有时甚至会减慢 SELECT
。
ANALYZE TABLE
将重新探测以刷新基数统计信息。这些值 可能 会改变,但 准确性 可能会或可能不会提高。
我首先在 table 中创建了 2 个单独的索引:uid 和 time。然后我决定创建一个复合索引(uid,时间)。 但是为什么复合索引(第 3 行)中 uid 的基数小于单个索引(第 1 行)中 uid 的基数?
mysql> show index from full_data;
+-----------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| full_data | 1 | uid | 1 | uid | A | 26394792 | NULL | NULL | YES | BTREE | | |
| full_data | 1 | time | 1 | time | A | 6934463 | NULL | NULL | YES | BTREE | | |
| full_data | 1 | composite | 1 | uid | A | 23166632 | NULL | NULL | YES | BTREE | | |
| full_data | 1 | composite | 2 | time | A | 86380688 | NULL | NULL | YES | BTREE | | |
+-----------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
4 rows in set (0.05 sec)
基数,在该上下文中,是基于对索引 BTree 的一些随机探测的粗略估计。 INDEX(uid)
执行一组随机探测; INDEX(uid, time)
探测不同的 BTree。
当您同时拥有 INDEX(uid)
和 INDEX(uid, time)
时,几乎没有必要保留前者。它会使磁盘混乱,增加 insert/update/delete 时间,并且不会显着加快 SELECT
。它有时甚至会减慢 SELECT
。
ANALYZE TABLE
将重新探测以刷新基数统计信息。这些值 可能 会改变,但 准确性 可能会或可能不会提高。