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>
相关文章
|
存储 关系型数据库 MySQL
InnoDB索引允许NULL对性能有影响吗(3)
InnoDB索引允许NULL对性能有影响吗
|
存储 SQL 关系型数据库
InnoDB索引允许NULL对性能有影响吗(1)
InnoDB索引允许NULL对性能有影响吗
|
存储 SQL 关系型数据库
InnoDB索引允许NULL对性能有影响吗(2)
InnoDB索引允许NULL对性能有影响吗
|
6天前
|
NoSQL Cloud Native Redis
Redis核心开发者的新征程:阿里云与Valkey社区的技术融合与创新
阿里云瑶池数据库团队后续将持续参与Valkey社区,如过往在Redis社区一样耕耘,为开源社区作出持续贡献。
Redis核心开发者的新征程:阿里云与Valkey社区的技术融合与创新
|
6天前
|
关系型数据库 分布式数据库 数据库
PolarDB闪电助攻,《香肠派对》百亿好友关系实现毫秒级查询
PolarDB分布式版助力《香肠派对》实现百亿好友关系20万QPS的毫秒级查询。
PolarDB闪电助攻,《香肠派对》百亿好友关系实现毫秒级查询
|
7天前
|
消息中间件 Cloud Native Serverless
RocketMQ 事件驱动:云时代的事件驱动有啥不同?
本文深入探讨了云时代 EDA 的新内涵及它在云时代再次流行的主要驱动力,包括技术驱动力和商业驱动力,随后重点介绍了 RocketMQ 5.0 推出的子产品 EventBridge,并通过几个云时代事件驱动的典型案例,进一步叙述了云时代事件驱动的常见场景和最佳实践。
115052 1
|
8天前
|
弹性计算 安全 API
访问控制(RAM)|云上安全使用AccessKey的最佳实践
集中管控AK/SK的生命周期,可以极大降低AK/SK管理和使用成本,同时通过加密和轮转的方式,保证AK/SK的安全使用,本次分享为您介绍产品原理,以及具体的使用步骤。
101814 1
|
7天前
|
自然语言处理 Cloud Native Serverless
通义灵码牵手阿里云函数计算 FC ,打造智能编码新体验
近日,通义灵码正式进驻函数计算 FC WebIDE,让使用函数计算产品的开发者在其熟悉的云端集成开发环境中,无需再次登录即可使用通义灵码的智能编程能力,实现开发效率与代码质量的双重提升。
95391 2
Doodle Jump — 使用Flutter&Flame开发游戏真不错!
用Flutter&Flame开发游戏是一种什么体验?最近网上冲浪的时候,我偶然发现了一个国外的游戏网站,类似于国内的4399。在浏览时,我遇到了一款经典的小游戏:Doodle Jump...
112734 12
|
12天前
|
SQL 存储 JSON
Flink+Paimon+Hologres 构建实时湖仓数据分析
本文整理自阿里云高级专家喻良,在 Flink Forward Asia 2023 主会场的分享。
71322 1
Flink+Paimon+Hologres 构建实时湖仓数据分析

热门文章

最新文章