MySQL 索引的一些细节分享

 更新时间:2020年12月28日 09:32:29   作者:Nicksxs  
这篇文章主要介绍了MySQL 索引的一些细节分享,帮助大家更好的理解和使用MySQL中的索引,感兴趣的朋友可以了解下

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

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;

用个存储过程来插入数据

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 查询

EXPLAIN select * from null_index_t WHERE null_key is null;

再来看看另一个

EXPLAIN select * from null_index_t WHERE null_key is not null;

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

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

然后再来看看执行结果

EXPLAIN select * from null_index_t WHERE null_key is null;

EXPLAIN select * from null_index_t WHERE null_key is not null;

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

以上就是MySQL 索引的一些细节分享的详细内容,更多关于MySQL 索引的资料请关注脚本之家其它相关文章!

相关文章

  • mysql5.7版本root密码登录问题的解决方法

    mysql5.7版本root密码登录问题的解决方法

    这篇文章主要为大家详细介绍了mysql5.7版本root密码登录问题的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • 一文学会Mysql数据库备份与恢复

    一文学会Mysql数据库备份与恢复

    数据库备份是在数据丢失的情况下能及时恢复重要数据,防止数据丢失的一种重要手段,下面这篇文章主要给大家介绍了关于Mysql数据库备份与恢复的相关资料,需要的朋友可以参考下
    2022-05-05
  • MySQL数据库导入导出数据之报错解答实例讲解

    MySQL数据库导入导出数据之报错解答实例讲解

    这篇文章主要介绍了MySQL数据库导入导出数据之报错解答实例讲解,文中对报错和解决方法做了详细的实例展示,有需要的同学可以借鉴参考下
    2021-02-02
  • MySQL使用binlog日志进行数据库迁移和数据恢复

    MySQL使用binlog日志进行数据库迁移和数据恢复

    MySQL的二进制日志是MySQL数据库中非常关键的一个组件,主要用于记录所有数据库表结构或表数据改变的操作语句,binlog是MySQL数据复制的基础,并且常常被用于数据恢复,本文给大家介绍了MySQL使用binlog日志进行数据库迁移和数据恢复,需要的朋友可以参考下
    2024-04-04
  • MySQL千万不要这样写update语句

    MySQL千万不要这样写update语句

    MySQL中update语句用于更新表中的现有数据,亦可用UPDATE语句来更改表中单个行,一组行或所有行的列值,这篇文章主要给大家介绍了关于MySQL千万不要这样写update语句的相关资料,需要的朋友可以参考下
    2021-11-11
  • win10下mysql5.7.21安装详细过程

    win10下mysql5.7.21安装详细过程

    这篇文章主要为大家详细介绍了win10下mysql5.7.21安装的详细过程,以及安装Mysql 5.7.21遇到的问题,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-02-02
  • MYSQL复杂查询练习题以及答案大全(难度适中)

    MYSQL复杂查询练习题以及答案大全(难度适中)

    在我们学习mysql数据库时需要一些题目进行练习,下面这篇文章主要给大家介绍了关于MYSQL复杂查询练习题以及答案的相关资料,文中通过实例代码介绍的非常详细,这些练习题难度适中,需要的朋友可以参考下
    2022-08-08
  • Mysql行锁和表锁的实现示例

    Mysql行锁和表锁的实现示例

    行锁和表锁是两种常见的锁定机制,本文主要介绍了Mysql行锁和表锁,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-08-08
  • MySql Group By对多个字段进行分组的实现方法

    MySql Group By对多个字段进行分组的实现方法

    这篇文章主要介绍了MySql Group By对多个字段进行分组的实现方法,需要的朋友可以参考下
    2017-09-09
  • Mysql DDL常见操作汇总

    Mysql DDL常见操作汇总

    这篇文章主要介绍了Mysql DDL常见操作汇总,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09

最新评论