有人可以向我解释为什么我会看到以下行为:
mysql> show index from history_historyentry;
+----------------------+------------+------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+----------------------+------------+------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| history_historyentry | 0 | PRIMARY | 1 | id | A | 48609 | NULL | NULL | | BTREE | |
+----------------------+------------+------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
1 row in set (0.00 sec)
mysql> explain SELECT COUNT(*) FROM `history_historyentry` WHERE `history_historyentry`.`is_deleted` = False;
+----+-------------+----------------------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------------+------+---------------+------+---------+------+-------+-------------+
| 1 | SIMPLE | history_historyentry | ALL | NULL | NULL | NULL | NULL | 48612 | Using where |
+----+-------------+----------------------+------+---------------+------+---------+------+-------+-------------+
1 row in set (0.00 sec)
mysql> explain SELECT COUNT(*) FROM `history_historyentry` WHERE `history_historyentry`.`is_deleted` = True;
+----+-------------+----------------------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------------+------+---------------+------+---------+------+-------+-------------+
| 1 | SIMPLE | history_historyentry | ALL | NULL | NULL | NULL | NULL | 48613 | Using where |
+----+-------------+----------------------+------+---------------+------+---------+------+-------+-------------+
1 row in set (0.00 sec)
mysql> create index deleted on history_historyentry (is_deleted) ;
Query OK, 48627 rows affected (0.38 sec)
Records: 48627 Duplicates: 0 Warnings: 0
mysql> explain SELECT COUNT(*) FROM `history_historyentry` WHERE `history_historyentry`.`is_deleted` = False;
+----+-------------+----------------------+-------+---------------+---------+---------+------+-------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------------+-------+---------------+---------+---------+------+-------+--------------------------+
| 1 | SIMPLE | history_historyentry | index | deleted | deleted | 1 | NULL | 36471 | Using where; Using index |
+----+-------------+----------------------+-------+---------------+---------+---------+------+-------+--------------------------+
1 row in set (0.00 sec)
mysql> explain SELECT COUNT(*) FROM `history_historyentry` WHERE `history_historyentry`.`is_deleted` = True;
+----+-------------+----------------------+------+---------------+---------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------------+------+---------------+---------+---------+-------+------+-------------+
| 1 | SIMPLE | history_historyentry | ref | deleted | deleted | 1 | const | 166 | Using index |
+----+-------------+----------------------+------+---------------+---------+---------+-------+------+-------------+
1 row in set (0.00 sec)
为什么True与False的索引使用率有差异?具体来说,在false的情况下,ref列是NULL,而额外的列是Using where;使用索引。但在真实情况下,ref列是const,而额外的列是Using index。
答案 0 :(得分:2)
大概是因为一个提供了良好的选择性而另一个没有,即只有一小部分行被删除。
如果基于成本的优化器提供良好的选择性(通常为10%),或者如果它是覆盖索引(在没有进一步的表或书签查找的情况下满足查询),则仅使用索引。