导读

假设这个用户中心系统是一个交友平台的一个子系统,现在产品想要提供一个按生日区间筛选用户的功能。那么,要实现这个功能,我们需要写这么一条SQL:

SELECT 

为了保证这条SQL的查询性能,我们会给用户表中的birthday字段添加索引。乍一看最初的表结构设计,好像已经有一个索引index_age_birth,这个索引包含了birthday字段,是不是可以用这个现成的索引,不再另加索引?

对MySQL有一些基本了解的开发同学知道MySQL InnoDB的索引查找是按照最左前缀匹配原则的,即SQL中的Where条件中的字段,如果要命中索引,必须按照该索引列的顺序逐一比对,最后定位查找结果。index_age_birth这个索引列的顺序为,明显age在前,birthday在后,所以,不满足最左前缀匹配原则,无法命中该索引。

所以,现在我们必须给birthday这个字段单独加上索引,见下图:

ALTER 

这时,你可能想到birthday这个字段,我们设的默认值为NULL,随之会产生一个疑问:如果某一个字段为NULL,以该字段作为条件进行查询,是否会影响我们查询的性能?今天这个章节,我们就先看看NULL这个值在InnoDB索引结构中是怎么存储的,然后,结合上面这条select查询SQL,看看MySQL又是如何执行这条SQL的,最后给到这个问题的答案。

存储结构

由于之前的用户表记录中没有birthday为NULL的记录,为了讲解NULL值对SQL查询性能的影响,我先添加一条birthday为NULL的记录,如下:

INSERT 

通过《基础篇》中,我对InnoDB索引结构的讲解,我们知道我加的这个index_birthday索引是一个辅助索引,所以,我们就来看一下NULL这个值在该辅助索引的结构是什么样的,如下图:

上图就是一颗birthday字段为索引的B-Tree,辅助索引的B-Tree结构,我在《基础篇》中详细讲解了,大家可以对照之前的讲解看下这张图,我在这里主要说一下NULL值的位置:NULL值被存储到了该辅助索引B-Tree的非叶节点页1、页2和叶子节点页4的最左边。也就说NULL记录总是出现在B-Tree的最左侧。

那么,针对本章《导读》中的这条select语句,MySQL又是如何查找索引的呢?为了方便浏览,我在这边再贴一下这条SQL:

SELECT 

查找过程

在前面的章节,我讲解过了MySQL查找辅助索引的整个过程,那么,结合这个例子,我再讲解一下MySQL是如何在index_birthday这个索引中查找[2007-01-02,2008-08-02]之间的记录的,见下图:

如上图,红色箭头部分,深度遍历这颗B-Tree:

  1. 页1 -> 页3,在页1中,发现2007-01-02大于2006-07-01,所以,箭头流向指向页3。
  2. 页3 -> 页6,发现2007-01-02位于[2006-07-01,2007-06-07]之间,所以,箭头流向指向页6。
  3. 由于页6为叶子节点,而辅助索引B-Tree所有节点内的记录按索引列升序排列,叶子节点之间是双向链表,叶子节点内记录组成单向链表,所以,发现页6中第一条大于等于2007-01-02的记录是<2007-06-06,6>,然后,从页6中的<2007-06-06,6>后开始,顺序遍历<2007-06-06,6>和页7的所有记录。
  4. 发现页7最后一条记录的age的值为2008-02-06,小于2008-08-02,因此,得到所有满足[2007-01-02,2008-08-02]之间的记录的主键6、8、2、5。
  5. 最后根据主键6、8、2、5,到聚簇索引中查询相应记录即可,关于详细查找过程,在这里我留一个悬念,在《IN字段查询多少个值最合适》这一章节中我会详细讲解。

小结

通过上述内容的讲解,我们知道了一张表中的一条记录中的某个字段a,它的值为NULL值,同时,a字段加了索引,那么

  1. a字段为NULL的记录一定出现在辅助索引非叶或叶子节点的最左边,采用深度遍历查找这条记录,效率是最高的。
  2. 查找a字段不为NULL的记录和NULL记录的数量无关,通过辅助索引B-Tree的二分查找是能很快定位到记录的。

所以,表结构中存在默认值为NULL的字段,并不会影响查询的性能。

思考

假设现在有这么两条记录,如下:

INSERT 

如果现在我写了这样一条SQL:

SELECT 

查找这两条记录的过程是怎么样的?

更多关于MySQL源码的解读内容,可以加vx群交流哦!或者知乎私信我,我都会回复的!

https://weixin.qq.com/g/AQYAAMmWP-ei65ZsYYGNtPd1Xt4-_tIcJO8jlAYRhlN1U1T0YdxXejTWCvh5X2sE (二维码自动识别)

case when影响性能吗_字段为NULL会影响查询性能吗?相关推荐

  1. java instanceof性能差_在J中使用instanceof的性能影响

    在J中使用instanceof的性能影响 我正在开发一个应用程序,一种设计方法涉及到instanceof运算符的极大使用. 虽然我知道OO设计通常会试图避免使用instanceof,但这是一个不同的故 ...

  2. 查询sql执行计划_使用SQL执行计划进行查询性能调整

    查询sql执行计划 In the previous articles of this series (see the index at bottom), we went through many as ...

  3. sql 行政区划关联查询优化_最新IP数据库 存储优化 查询性能优化 每秒解析上千万...

    高性能IP数据库格式详解 每秒解析1000多万ip  qqzeng-ip-ultimate.dat 3.0版编码:UTF8字节序:Little-Endian 返回规范字段(如:亚洲|中国|香港|九龙| ...

  4. 微服务架构 性能提升_如何通过无服务器架构提高性能

    微服务架构 性能提升 by Domenico Angilletta 通过多梅尼科·安吉列塔(Domenico Angilletta) 如何通过无服务器架构提高性能 (How to boost your ...

  5. sql 查询数据库索引重建_不良的数据库索引– SQL查询性能的杀手–建议

    sql 查询数据库索引重建 previous article, we explained what clustered and nonclustered indexes were, and showe ...

  6. display会影响canvas吗_多动症会影响智商吗?

    小智(化名)小的时候非常皮,上学了也不老实,学习成绩还很差,一直是倒数,还有人说他智商低.父母带他到医院检查,一切都正常,智商也没问题.直到最近他被检查出多动症,小智的妈妈就慌了,她很疑惑,多动症会影 ...

  7. mysql not null 性能_如何使用NULL提高MySQL查询的性能?

    下表中有几百万条记录: CREATE TABLE `customers` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `store_id` int ...

  8. java常见性能优化_十大最常见的Java性能问题

    java常见性能优化 Java性能是所有Java应用程序开发人员都关心的问题,因为快速使应用程序与使其正常运行同等重要. 史蒂文·海恩斯(Steven Haines)使用他在Java性能问题上的个人经 ...

  9. sql server management studio性能分析_如何分析一条SQL的性能

    来自公众号:谭小谭 这篇文章将给大家介绍如何使用 explain 来分析一条 sql . 网上其实已经有非常多的文章都很详细的介绍了 explain 的使用,这篇文章将实例和原理结合起来,尽量让你有更 ...

最新文章

  1. 推荐一位Python终生学习者!本科期间用Python赚了10w+!
  2. 大数据WEB 部署项目到linux中
  3. #linux# su命令细节错误
  4. SQL Server 中 JSON_MODIFY 的使用
  5. LeetCode 1431. 拥有最多糖果的孩子
  6. decimal转为string sql_PHP+Mysql防止SQL注入的方法
  7. 支付宝用大数据憋死伪基站骗子
  8. java学习之路之播放一首简单的音乐
  9. AssertJ断言系列一
  10. java informix 实例
  11. 【Tensorlayer系列】深度强化学习之DQN求解FrozenLake
  12. 不得不学的统计学基础知识(一)
  13. TA入门笔记(十五)
  14. 关于程序化交易 这篇文章说透了
  15. 酒水知识(六大基酒之白兰地_Brandy)
  16. 计算机电源出现问题,电源故障引起的电脑问题
  17. MongoDB单机集群搭建
  18. java_home的配置
  19. 计算机毕业设计Android宠物领养救助系统app(源码+系统+mysql数据库+Lw文档)
  20. 异常检测 | Street Scene

热门文章

  1. DotNetCore跨平台~配置文件与配置代码如何共存
  2. Entity Framework中的字符串插值引发担忧
  3. .NET Core Tools 1.0 版本
  4. [开源 .NET 跨平台 数据采集 爬虫框架: DotnetSpider] [一] 初衷与架构设计
  5. [转]面向对象(1、三大特征;2、六大原则)
  6. [转].NET 开源项目 Anet 介绍
  7. 【ArcGIS遇上Python】ArcGIS批量处理栅格影像(NDVI)归一化完整案例代码
  8. Android之简单的文件夹选择器实现
  9. C和指针之函数之实现阶乘和斐波那契数(递归和非递归)
  10. C++之undefined reference to “ssl::first::first()“