InnoDB索引允许NULL对性能有影响吗(2)

简介: InnoDB索引允许NULL对性能有影响吗


这次的查询需要扫描12个page,除去1个根节点外,还需要扫描12个叶子节点,只是为了返回一条数据而已,这代价有点大。

如果把SQL微调改成下面这样

[root@yejr.run]> select id,c1 from t_sk where c1 is null limit 10000,1;
+-------+------+
| id    | c1   |
+-------+------+
| 99671 | NULL |
+-------+------+



可以看到还是需要扫描12个page。

InnoDB_pages_distinct: 12

...
select id,c1 from t_sk where c1 is null limit 10000,1;



SQL3, 查询 c1 任意非NULL值

如果把 c1列条件改成正常的int值,结果就不太一样了

[root@yejr.run]> select id, c1 from t_sk where c1  = 907299016;
+--------+-----------+
| id | c1 |
+--------+-----------+
| 365115 | 907299016 |
+--------+-----------+
1 row in set (0.00 sec)

slow log是这样的

InnoDB_pages_distinct: 2
...
select id, c1 from t_sk where c1 = 907299016;



可以看到,只需要扫描2个page,这个看起来就正常了。

结论1,存储大量的NULL值,除了计算更复杂之外,数据扫描的代价也会更高一些


另外,如果要查询的c1值正好介于两个page的临界位置,那么需要多读取一个page。

扫描第31号page,确认该数据页中的最小和最大物理记录

[root@yejr.run]# innodb_space -s ibdata1 -T test/t_sk -p 31 page-dump
...
records:
{:format=>:compact,
:offset=>126,
:header=>
{:next=>9996,
:type=>:conventional,
:heap_number=>2,
:n_owned=>0,
:min_rec=>false,
:deleted=>false,
:nulls=>[],
:lengths=>{},
:externs=>[],
:length=>6},
:next=>9996,
:type=>:secondary,
:key=>[{:name=>"c1", :type=>"INT UNSIGNED", :value=>1531865685}],
:row=>[{:name=>"id", :type=>"INT UNSIGNED", :value=>1507}],
:sys=>[],
:length=>8}
...
{:format=>:compact,
:offset=>5810,
:header=>
{:next=>112,
:type=>:conventional,
:heap_number=>408,
:n_owned=>0,
:min_rec=>false,
:deleted=>false,
:nulls=>[],
:lengths=>{},
:externs=>[],
:length=>6},
:next=>112,
:type=>:secondary,
:key=>[{:name=>"c1", :type=>"INT UNSIGNED", :value=>1536700825}],
:row=>[{:name=>"id", :type=>"INT UNSIGNED", :value=>361382}],
:sys=>[],
:length=>8}



指定c1的值为 1531865685、1536700825 执行查询,查看slow log,确认都需要扫描3个page,而如果换成介于这两个值之间的数据,则只需要扫描2个page。

InnoDB_pages_distinct: 3
...
select id, c1 from t_sk where c1 = 1531865685;

InnoDB_pages_distinct: 3
...
select id, c1 from t_sk where c1 = 1536700825;

InnoDB_pages_distinct: 2
...
select id, c1 from t_sk where c1 = 1536630003;

InnoDB_pages_distinct: 2
...
select id, c1 from t_sk where c1 = 1536575377;



这是因为辅助索引是非唯一的,即便是在等值查询时,也需要再读取下一条记录,以确认已获取所有符合条件的数据。

还有,当利用辅助索引读取数据时,如果要读取整行数据,则需要回表。

也就是说,除了扫描辅助索引数据页之外,还需要扫描聚集索引数据页。

来个例子看看就知道了。

#无需回表时
InnoDB_pages_distinct: 2
...
select id, c1 from tnull where c1 = 1536630003;

#需要回表时
InnoDB_pages_distinct: 5
...
select * from t_sk where c1 = 1536630003;

需要回表时,除了扫描辅助索引页2个page外,还需要回表扫描聚集索引页,而聚集索引是个3层树,因此总共需要扫描5个page。


            </div>
相关文章
|
存储 SQL 关系型数据库
InnoDB索引允许NULL对性能有影响吗(1)
InnoDB索引允许NULL对性能有影响吗
|
存储 SQL 关系型数据库
InnoDB索引允许NULL对性能有影响吗(2)
InnoDB索引允许NULL对性能有影响吗
|
存储 关系型数据库 MySQL
InnoDB索引允许NULL对性能有影响吗(3)
InnoDB索引允许NULL对性能有影响吗
|
4天前
|
弹性计算 安全 API
访问控制(RAM)|云上安全使用AccessKey的最佳实践
集中管控AK/SK的生命周期,可以极大降低AK/SK管理和使用成本,同时通过加密和轮转的方式,保证AK/SK的安全使用,本次分享为您介绍产品原理,以及具体的使用步骤。
101783 0
|
4天前
|
SQL 关系型数据库 分布式数据库
Doodle Jump — 使用Flutter&Flame开发游戏真不错!
用Flutter&Flame开发游戏是一种什么体验?最近网上冲浪的时候,我偶然发现了一个国外的游戏网站,类似于国内的4399。在浏览时,我遇到了一款经典的小游戏:Doodle Jump...
|
12天前
|
弹性计算 运维 安全
访问控制(RAM)|云上程序使用临时凭证的最佳实践
STS临时访问凭证是阿里云提供的一种临时访问权限管理服务,通过STS获取可以自定义时效和访问权限的临时身份凭证,减少长期访问密钥(AccessKey)泄露的风险。本文将为您介绍产品原理,以及具体的使用步骤。
151033 4
|
10天前
|
数据采集 存储 运维
提升团队工程交付能力,从“看见”工程活动和研发模式开始
本文从统一工程交付的概念模型开始,介绍了如何将应用交付的模式显式地定义出来,并通过工具平台落地。
119990 57
|
11天前
|
监控 负载均衡 Java
深入探究Java微服务架构:Spring Cloud概论
**摘要:** 本文深入探讨了Java微服务架构中的Spring Cloud,解释了微服务架构如何解决传统单体架构的局限性,如松耦合、独立部署、可伸缩性和容错性。Spring Cloud作为一个基于Spring Boot的开源框架,提供了服务注册与发现、负载均衡、断路器、配置中心、API网关等组件,简化了微服务的开发、部署和管理。文章详细介绍了Spring Cloud的核心模块,如Eureka、Ribbon、Hystrix、Config、Zuul和Sleuth,并通过一个电商微服务系统的实战案例展示了如何使用Spring Cloud构建微服务应用。
103502 8
|
12天前
|
人工智能 Serverless 对象存储
让你的文档从静态展示到一键部署可操作验证
通过函数计算的能力让阿里云的文档从静态展示升级为动态可操作验证,用户在文档中单击一键部署可快速完成代码的部署及测试。这一改变已在函数计算的活动沙龙中得到用户的认可。
120839 218