Mysql实战题目,如何加索引?
实战题目
select * from t where a=? and b>? order by c limit 0,100 如何加索引
测试环境
mysql> select version() ;
+-----------+
| version() |
+-----------+
| 8.0.17 |
+-----------+
1 row in set (0.01 sec)
附
快速搭建一个指定版本的Mysql https://blog.csdn.net/hl_java/article/details/90259538
表及数据准备
drop table if exists t;
create table t(
id int primary key auto_increment,
a int ,
b int ,
c int
) ENGINE=InnoDB;
drop procedure if exists add_data;
DELIMITER ;;
CREATE PROCEDURE add_data(IN loop_times INT)
BEGIN
DECLARE var INT DEFAULT 1;
WHILE var <= loop_times DO
INSERT INTO t VALUES (NULL,var%100,var ,var);
SET var = var + 1;
END WHILE;
END
;;
DELIMITER ;
SET @type = 100000;
CALL add_data(@type);
不同场景测试
SQL1
select * from t where a=10 and b>50000 order by c limit 0,100 ;
说明:根据插入的数据我们提前分析sql查询的结果集为500,然后limt之后就只返回100条了
SQL2
select * from t where a=10 and b>100 order by c limit 0,100 ;
说明:根据插入的数据我们提前分析sql查询的结果集为999,然后limt之后就只返回100条了
仅有主键索引的情况
select * from t where a=10 and b>50000 order by c limit 0,100 ;
100 rows in set (0.03 sec)
select * from t where a=10 and b>100 order by c limit 0,100 ;
100 rows in set (0.03 sec)
附
mysql> explain select * from t where a=10 and b>50000 order by c limit 0,100 ;
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-----------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-----------------------------+
| 1 | SIMPLE | t | NULL | ALL | NULL | NULL | NULL | NULL | 100169 | 3.33 | Using where; Using filesort |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-----------------------------+
1 row in set, 1 warning (0.01 sec)
mysql> explain select * from t where a=10 and b>100 order by c limit 0,100 ;
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-----------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-----------------------------+
| 1 | SIMPLE | t | NULL | ALL | NULL | NULL | NULL | NULL | 100169 | 3.33 | Using where; Using filesort |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-----------------------------+
1 row in set, 1 warning (0.00 sec)
增加字段a索引的情况
alter table t add index idx_a (a);
select * from t where a=1 and b>50000 order by c limit 0,100 ;
100 rows in set (0.01 sec)
select * from t where a=1 and b>100 order by c limit 0,100 ;
100 rows in set (0.01 sec)
附
explain select * from t where a=1 and b>50000 order by c limit 0,100 ;
+----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-----------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-----------------------------+
| 1 | SIMPLE | t | NULL | ref | idx_a | idx_a | 5 | const | 1000 | 33.33 | Using where; Using filesort |
+----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-----------------------------+
1 row in set, 1 warning (0.00 sec)
explain select * from t where a=1 and b>100 order by c limit 0,100 ;
+----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-----------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-----------------------------+
| 1 | SIMPLE | t | NULL | ref | idx_a | idx_a | 5 | const | 1000 | 33.33 | Using where; Using filesort |
+----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-----------------------------+
1 row in set, 1 warning (0.00 sec)
增加字段a,b联合索引的情况
alter table t add index idx_ab (a,b);
select * from t where a=10 and b>50000 order by c limit 0,100 ;
100 rows in set (0.00 sec)
select * from t where a=10 and b>100 order by c limit 0,100 ;
100 rows in set (0.01 sec)
附
explain select * from t where a=10 and b>50000 order by c limit 0,100 ;
+----+-------------+-------+------------+-------+---------------+--------+---------+------+------+----------+---------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+--------+---------+------+------+----------+---------------------------------------+
| 1 | SIMPLE | t | NULL | range | idx_ab | idx_ab | 10 | NULL | 500 | 100.00 | Using index condition; Using filesort |
+----+-------------+-------+------------+-------+---------------+--------+---------+------+------+----------+---------------------------------------+
1 row in set, 1 warning (0.00 sec)
explain select * from t where a=10 and b>100 order by c limit 0,100 ;
+----+-------------+-------+------------+-------+---------------+--------+---------+------+------+----------+---------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+--------+---------+------+------+----------+---------------------------------------+
| 1 | SIMPLE | t | NULL | range | idx_ab | idx_ab | 10 | NULL | 999 | 100.00 | Using index condition; Using filesort |
+----+-------------+-------+------------+-------+---------------+--------+---------+------+------+----------+---------------------------------------+
1 row in set, 1 warning (0.00 sec)
增加字段a,c联合索引的情况
alter table t drop index idx_ab;
alter table t add index idx_ac (a,c);
select * from t where a=10 and b>50000 order by c limit 0,100 ;
100 rows in set (0.00 sec)
select * from t where a=10 and b>100 order by c limit 0,100 ;
100 rows in set (0.01 sec)
附
explain select * from t where a=10 and b>50000 order by c limit 0,100 ;
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | t | NULL | ref | idx_ac | idx_ac | 5 | const | 1000 | 33.33 | Using where |
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.01 sec)
explain select * from t where a=10 and b>100 order by c limit 0,100 ;
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | t | NULL | ref | idx_ac | idx_ac | 5 | const | 1000 | 33.33 | Using where |
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
增加字段a,b,c联合索引的情况
alter table t drop index idx_ac;
alter table t add index idx_abc (a,b,c);
select * from t where a=10 and b>50000 order by c limit 0,100 ;
100 rows in set (0.00 sec)
select * from t where a=10 and b>100 order by c limit 0,100 ;
100 rows in set (0.00 sec)
附
explain select * from t where a=10 and b>50000 order by c limit 0,100 ;
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+------------------------------------------+
| 1 | SIMPLE | t | NULL | range | idx_abc | idx_abc | 10 | NULL | 500 | 100.00 | Using where; Using index; Using filesort |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+------------------------------------------+
1 row in set, 1 warning (0.00 sec)
explain select * from t where a=10 and b>100 order by c limit 0,100 ;
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+------------------------------------------+
| 1 | SIMPLE | t | NULL | range | idx_abc | idx_abc | 10 | NULL | 999 | 100.00 | Using where; Using index; Using filesort |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+------------------------------------------+
1 row in set, 1 warning (0.00 sec)
增加字段c,a,b联合索引的情况
alter table t drop index idx_abc;
alter table t add index idx_cab (c,a,b);
select * from t where a=10 and b>50000 order by c limit 0,100 ;
100 rows in set (0.02 sec)
select * from t where a=10 and b>100 order by c limit 0,100 ;
100 rows in set (0.00 sec)
附
explain select * from t where a=10 and b>50000 order by c limit 0,100 ;
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
| 1 | SIMPLE | t | NULL | index | idx_cab | idx_cab | 15 | NULL | 100 | 3.33 | Using where; Using index |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)
explain select * from t where a=10 and b>100 order by c limit 0,100 ;
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
| 1 | SIMPLE | t | NULL | index | idx_cab | idx_cab | 15 | NULL | 100 | 3.33 | Using where; Using index |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)
单纯从执行时间上看,有点迷茫了。
加完上述任一一个索引后,都比不加索引要好,但是执行耗时都在0.01 ~ 0.02 sec之间
,区别不大,结论不好总结
看接下来的2篇会给出结论