mysql的innodb引擎索引优化

在数据量较小时,innodb引擎会自行优化,有时候不会使用索引。

创建数据库:

/*
 Navicat Premium Data Transfer

 Source Server         : 127.0.0.1
 Source Server Type    : MySQL
 Source Server Version : 50721
 Source Host           : 127.0.0.1
 Source Database       : test

 Target Server Type    : MySQL
 Target Server Version : 50721
 File Encoding         : utf-8

 Date: 06/20/2018 11:02:19 AM
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
--  Table structure for `class`
-- ----------------------------
DROP TABLE IF EXISTS `class`;
CREATE TABLE `class` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `class_name` varchar(128) DEFAULT NULL,
  `teacher_id` int(11) DEFAULT NULL,
  `count` int(11) DEFAULT NULL,
  `rank` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_class_name_teacher_id_count` (`class_name`,`teacher_id`,`count`) USING BTREE,
  KEY `idx_t` (`teacher_id`) USING BTREE,
  KEY `idx_t_c_r` (`teacher_id`,`count`,`rank`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

-- ----------------------------
--  Records of `class`
-- ----------------------------
BEGIN;
INSERT INTO `class` VALUES ('1', 'class1', '1', '50', '1'), ('2', 'class2', '3', '51', '2'), ('3', 'class3', '1', '50', '1'), ('4', 'class4', '1', '48', '1'), ('5', 'class5', '1', '52', '2'), ('6', 'class6', '2', '45', '3');
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;

做个查询:

mysql> select * from class;
+----+------------+------------+-------+------+
| id | class_name | teacher_id | count | rank |
+----+------------+------------+-------+------+
|  1 | class1     |          1 |    50 |    1 |
|  2 | class2     |          3 |    51 |    2 |
|  3 | class3     |          1 |    50 |    1 |
|  4 | class4     |          1 |    48 |    1 |
|  5 | class5     |          1 |    52 |    2 |
|  6 | class6     |          2 |    45 |    3 |
+----+------------+------------+-------+------+
6 rows in set (0.00 sec)

奇怪的问题

分析sql

分析sql:explain select * from class where teacher_id = 1;

mysql> explain select * from class where teacher_id = 1;
+----+-------------+-------+------------+------+-----------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys   | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+-----------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | class | NULL       | ALL  | idx_t,idx_t_c_r | NULL | NULL    | NULL |    6 |    66.67 | Using where |
+----+-------------+-------+------------+------+-----------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

发现type为ALL,没用使用索引。

  • 重新做分析

分析sql:explain select * from class where teacher_id = 3;

mysql> explain select * from class where teacher_id = 3;
+----+-------------+-------+------------+------+-----------------+-------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys   | key   | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+-----------------+-------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | class | NULL       | ref  | idx_t,idx_t_c_r | idx_t | 5       | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+-----------------+-------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

发现用了索引,type为ref,结果喜人。

原因

由于索引扫描后要利用索引中的指针去逐一访问记录,假设每个记录都使用索引访问,则读取磁盘的次数是查询包含的记录数T,而如果表扫描则读取磁盘的次数是存储记录的块数B,如果T>B 的话索引就没有优势了。对于大多数数据库来说,这个比例是10%(oracle,postgresql等),即先对结果数量估算,如果小于这个比例用索引,大于的话即直接表扫描。

https://www.zhihu.com/question/51004639/answer/123766749

这里,①中会有4条数据,T=4,B=? 后续解答。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • -1- 人,为什么做事情坚持不下来? 因为懒。 为什么懒? 因为跟自己说那些事情其实不做也可以。 为什么不做也可以...
    蜕变的林林阅读 3,226评论 1 0
  • 一直在想, 你的事情, 所以 今天, 我人生中的一刻, 你轻轻地来了, 庆祝, 因为 这是第一次啊, 是我真正地喜...
    橙优阅读 3,068评论 0 3
  • 故事有点长,孩子想吃零食,而我不同意,彼此有了激烈的情绪,他打我,我也揍了他。孩子的情绪得到接纳,最后找到了彼此都...
    心鑫觉察日记阅读 3,398评论 0 7
  • 8月24日,来到大连的第六天。 今天计划去金石滩,有很多人推荐我去,也有一些人不推荐我去。我还是决定自己亲自去看看...
    花悠然阅读 3,567评论 17 2
  • 【烨煜生辉】2017.12.23 学习力七期践行记录 D74 又到周末,时间过得真是飞快,2017年已接近尾声,回...
    烨妈阅读 981评论 0 0