mysql5.7决定SQL中IN条件是否走索引的成本计算

一、表和索引设计

CREATE TABLE `t_user`  (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT ‘primary key‘,
  `username` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT ‘user name‘,
  `age` int(4) NOT NULL DEFAULT 20 COMMENT ‘user age‘,
  `birthday_date_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘user birthday‘,
  `address` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
  `remark` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT ‘remark something‘,
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘create time‘,
  `version` int(4) NOT NULL DEFAULT 0 COMMENT ‘update version‘,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `idx_name`(`username`) USING BTREE,
  INDEX `idx_age_remark`(`age`, `remark`) USING BTREE,
  INDEX `idx_create_time`(`create_time`) USING BTREE,
  INDEX `idx_address`(`address`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 10003 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = DYNAMIC;

二、mysql预估表行数,和索引不重复行数

2.1)mysql预估t_user表行数 9964行:

mysql5.7决定SQL中IN条件是否走索引的成本计算

2.2)mysql预估t_user表各个索引不重复数据行数:show index from t_user;

mysql5.7决定SQL中IN条件是否走索引的成本计算

Non_unique : 是否为唯一索引
Key_name : 索引名称
Seq_in_index : 索引列顺序,如果是联合索引,就会有数字排序123这样子,其他单个列索引都是1
Cardinality : 索引基数。估算的该索引列的不重复值数据行数,所以如果该值和表行数数据一样,说明该索引列没有重复值。
Index_type : 索引类型,一般是BTREE索引

三、执行成本计算

在两个区间之间计算有多少条记录的方式,在mysql中被称为index dive。如果一个SQL 用了 IN (2万个参数,或者一个子查询SQL结果集非常多的),那么mysql很有可能认为走全表扫描更快。
查看mysql的index dive参数值:

SHOW VARIABLES LIKE ‘%dive%‘;  -- 默认 eq_range_index_dive_limit = 200


也就是当IN条件里的参数个数不超过200时,mysql才走index dive,去精确统计有多少行数,超过200个了,myslq会使用索引统计数据进行估算。那

 

end.

mysql5.7决定SQL中IN条件是否走索引的成本计算

上一篇:7月5日云栖精选夜读:物联网技术在农业领域的应用


下一篇:Spark SQL 原理