您的位置:首页 > 数据库 > > 正文

终于有人将mysql 索引讲清楚了(MySQL 索引的一些细节分享)

更多 时间:2022-01-23 02:47:13 类别:数据库 浏览量:123

终于有人将mysql 索引讲清楚了

MySQL 索引的一些细节分享

前几天同事问了我个 mysql 索引的问题,虽然大概知道,但是还是想来实践下,就是 is null,is not null 这类查询是否能用索引,可能之前有些网上的文章说都是不能用索引,但是其实不是,我们来看个小试验

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • CREATE TABLE `null_index_t` (
  •  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  •  `null_key` varchar(255) DEFAULT NULL,
  •  `null_key1` varchar(255) DEFAULT NULL,
  •  `null_key2` varchar(255) DEFAULT NULL,
  •  PRIMARY KEY (`id`),
  •  KEY `idx_1` (`null_key`) USING BTREE,
  •  KEY `idx_2` (`null_key1`) USING BTREE,
  •  KEY `idx_3` (`null_key2`) USING BTREE
  • ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  • 用个存储过程来插入数据

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • delimiter $ #以delimiter来标记用$表示存储过程结束
  • create procedure nullIndex1()
  • begin
  • declare i int
  • declare j int
  • set i=1;
  • set j=1;
  • while(i<=100) do
  •     while(j<=100) do
  •         IF (i % 3 = 0) THEN
  •        INSERT INTO null_index_t ( `null_key`, `null_key1`, `null_key2` ) VALUES (null , LEFT(MD5(RAND()), 8), LEFT(MD5(RAND()), 8));
  •   ELSEIF (i % 3 = 1) THEN
  •              INSERT INTO null_index_t ( `null_key`, `null_key1`, `null_key2` ) VALUES (LEFT(MD5(RAND()), 8), NULL, LEFT(MD5(RAND()), 8));
  •      ELSE
  •              INSERT INTO null_index_t ( `null_key`, `null_key1`, `null_key2` ) VALUES (LEFT(MD5(RAND()), 8), LEFT(MD5(RAND()), 8), NULL);
  •   END IF;
  •         set j=j+1;
  •     end while;
  •     set i=i+1;
  •     set j=1;   
  • end while;
  • end
  • $
  • call nullIndex1();
  • 然后看下我们的 is null 查询

  • ?
  • 1
  • EXPLAIN select * from null_index_t WHERE null_key is null;
  • 终于有人将mysql 索引讲清楚了(MySQL 索引的一些细节分享)

    再来看看另一个

  • ?
  • 1
  • EXPLAIN select * from null_index_t WHERE null_key is not null;
  • 终于有人将mysql 索引讲清楚了(MySQL 索引的一些细节分享)

    从这里能看出来啥呢,可以思考下

    从上面可以发现,is null应该是用上了索引了,所以至少不是一刀切不能用,但是看着is not null好像不太行额
    我们在做一点小改动,把这个表里的数据改成 9100 条是 null,剩下 900 条是有值的,然后再执行下

    终于有人将mysql 索引讲清楚了(MySQL 索引的一些细节分享)

    然后再来看看执行结果

  • ?
  • 1
  • EXPLAIN select * from null_index_t WHERE null_key is null;
  • 终于有人将mysql 索引讲清楚了(MySQL 索引的一些细节分享)

  • ?
  • 1
  • EXPLAIN select * from null_index_t WHERE null_key is not null;
  • 终于有人将mysql 索引讲清楚了(MySQL 索引的一些细节分享)

    是不是不一样了,这里再补充下我试验使用的 mysql 是 5.7 的,不保证在其他版本的一致性,
    其实可以看出随着数据量的变化,mysql 会不会使用索引是会变化的,不是说 is not null 一定会使用,也不是一定不会使用,而是优化器会根据查询成本做个预判,这个预判尽可能会减小查询成本,主要包括回表啥的,但是也不一定完全准确。

    以上就是MySQL 索引的一些细节分享的详细内容,更多关于MySQL 索引的资料请关注开心学习网其它相关文章!

    原文链接:https://nicksxs.me/2020/12/27/%E8%81%8A%E8%81%8A-mysql-%E7%B4%A2%E5%BC%95%E7%9A%84%E4%B8%80%E4%BA%9B%E7%BB%86%E8%8A%82/

    您可能感兴趣