机智的MySQL优化器 --- is null
【介绍】
工作的越久越到的的问题越多,就越是觉得一些“老话”历久弥新;由于最近的学习计划是深入的学习一遍MySQL优化器;学习过程中的一些成果
也会发布到这里,一来是为了整理自己已经知道的和新学到的,二来是为了给自己的网站做个友情连接
【is null 优化】
如果我们在定义表的时候就给不能为null的列加上not null 那么就将是一个非常好的实践,想想如果接下来有查询要查找col is null的话,因为mysql
已经知道col不可能为null 所以MySQL会直接把这个优化掉,返回空结果集;理由是根本不会存在col is null的行
【看一下is null 有多吊吧】
第一步:建立一个测试表
create table t(id int not null auto_increment primary key, x int not null,y int); create index idx_t_x on t(x); -- x 是not null 的 create index idx_t_y on t(y); -- y 是可以为空的 insert into t(x,y) values(1,null),(2,2),(3,3);
第二步:观察MySQL针对null 和 not null的列的处理是有本质区别的
explain select x from t where x is null;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible WHERE |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+
1 row in set, 1 warning (0.00 sec)
由于x 不可能为空,所以当查询条件是x is null的情况下MySQL不用去查就直接返回了空结果集,正确+省事
mysql> explain select x from t where y is null;
+----+-------------+-------+------------+------+---------------+---------+---------+-------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+---------+---------+-------+------+----------+-----------------------+
| 1 | SIMPLE | t | NULL | ref | idx_t_y | idx_t_y | 5 | const | 1 | 100.00 | Using index condition |
+----+-------------+-------+------------+------+---------------+---------+---------+-------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
由于y是可以为null的、所以表的访问过程就变成了先读索引再回表(ref),就算y中的每一行都有值,其过程还是要比上面的x is null的查询要多做不少
第三步:不管列上有没有索引只要表定义中指定了条件不为null那么针对is null查询还是可以得到优化
alter table t add column z int; explain select x from t where z is null;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | t | NULL | ALL | NULL | NULL | NULL | NULL | 3 | 33.33 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
由于z上没有索引也没有定义成 not null 所以针对 z is null只能直接全表扫描、下面看一下定义了not null的情况
alter table t drop column z; alter table t add column z int not null; -- 在这种没有指定默认值的情况下、int类型默认为0
explain select * from t where z is null;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible WHERE |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+
1 row in set, 1 warning (0.00 sec)
【总结】
not null 应该算是关系模板中域完整性的一部分吧,这个已经是关系型数据库中的一部分;在定义表的时候就应该尽可能的把完整性加进去,这样优化
器得到的信息更多,做出的选择也更加机智。
【我的个站点】
---
机智的MySQL优化器 --- is null的更多相关文章
- 0104探究MySQL优化器对索引和JOIN顺序的选择
转自http://www.jb51.net/article/67007.htm,感谢博主 本文通过一个案例来看看MySQL优化器如何选择索引和JOIN顺序.表结构和数据准备参考本文最后部分" ...
- 数据库 mysql 优化器原理
MySQL查询优化器有几个目标,但是其中最主要的目标是尽可能地使用索引,并且使用最严格的索引来消除尽可能多的数据行. 你的最终目标是提交SELECT语句查找数据行,而不是排除数据行.优化器试图排除数据 ...
- MySQL优化器cost计算
记录MySQL 5.5上,优化器进行cost计算的方法. 第一篇: 单表的cost计算 数据结构: 1. table_share: 包含了表的元数据,其中索引部分: key_info:一个key的结构 ...
- MySQL优化器 --- index_merge
[背景] 对于关系数据库中的一张表,通常来说数据页面的总大小要比较某一个索引占用的页面要大的多(上面说的索引是不包涵主键索引的); 更进一步我们可以推导出,如果我们通过读索引就能解决问题,那么它相比读 ...
- MySQL优化器功能开关optimizer_switch
MySQL 8.0新增特性 use_invisible_indexes:是否使用不可见索引,MySQL 8.0新增可以创建invisible索引,这一开关控制优化器是否使用invisible索引,on ...
- mysql 优化之 is null ,is not null 索引使用测试
关于mysql优化部分,有很多网友说尽量避免使用is null, is not null,select * 等,会导致索引失效,性能降低?那是否一定收到影响呢?真的就不会使用索引了吗? 本文的测试数据 ...
- 《Mysql - 优化器是如何选择索引的?》
一:概念 - 在 索引建立之后,一条语句可能会命中多个索引,这时,索引的选择,就会交由 优化器 来选择合适的索引. - 优化器选择索引的目的,是找到一个最优的执行方案,并用最小的代价去执行语句. 二: ...
- 如何干涉MySQL优化器使用hash join
GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. GreatSQL是MySQL的国产分支版本,使用上与MySQL一致. 前言 实验 总结 前言 数据库的优化器相当于人类的大 ...
- MySQL优化器不使用索引的情况
优化器选择不适用索引的情况 有时候,有乎其并没有选择索引而去查找数据,而是通过扫描聚集索引,也就是直接进行全表的扫描来得到数据.这种情况多发生于范围查找.JOIN链接操作等情况.例如 ; 通过SHOW ...
随机推荐
- 自定义Map.Entry的Comperator实现字符频率降序排序
leetCode (#451,middle) java实现 class Solution { public String frequencySort(String s) { Map<Charac ...
- C#Workbooks 对象的 Open 方法参数说明
打开一个工作簿. excelApp.Open(FileName, UpdateLinks, ReadOnly, Format, Password, WriteResPassword,IgnoreRea ...
- emitted value instead of an instance of error the scope attribute for scoped slots webpack babel polyfill
api20180803.vue emitted value instead of an instance of error the scope attribute for scoped slots h ...
- 潭州课堂25班:Ph201805201 tornado 项目 第一课 项目介绍和创建 (课堂笔记)
tornado 相关说明 , 查找 python3 的路径: binbin@abc:~$ which python3/usr/bin/python3 创建虚拟环境 : 创建工程; 用 pycharm ...
- IntelliJ IDEA无法更新maven索引
maven索引的作用时在添加dependency的时候能有自动提示,不影响dependency的下载: 解决办法: 1.http://ju.outofmemory.cn/entry/359450 2. ...
- React生命周期函数详解
React生命周期函数 生命周期函数是指在某一个周期自动执行的函数. React中的生命周期执行过程 以下是React中的常用的生命周期函数,按个部分中按照自动执行顺序列出,这几个过程可能存在同时进行 ...
- C++程序设计方法3:类中的静态成员
在类型前面加static修饰的数据成员,是隶属于类的,成为类的静态数据成员,也称为“类的变量” 静态数据成员被该类的所有对象共享(即所有对象中的这个数据域实际上处于同一个内存位置) 静态数据要在实现文 ...
- yii动态配置International(Yii::t())
Yii:t()的动态配置 \Yii::$app->i18n->translations['categoryName*'] = [ 'class' => 'yii\i18n\PhpMe ...
- Python类的几点笔记
1. class A: def __init__(self, a, b): self.a = a self.b = b print(a, b) class B(A): def __init__(sel ...
- 安装oracle11g不能启动图形化界面
问题:安装oracle11g时出现xhost: unable to open display "192.168.2.12:0.0".打不开图形化界面等. 终极解决方法:1.使用X ...