介绍

  工作的越久越到的的问题越多,就越是觉得一些“老话”历久弥新;由于最近的学习计划是深入的学习一遍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 应该算是关系模板中域完整性的一部分吧,这个已经是关系型数据库中的一部分;在定义表的时候就应该尽可能的把完整性加进去,这样优化

  器得到的信息更多,做出的选择也更加机智。

【我的个站点】

  www.sqlpy.com

---

最新文章

  1. js模版引擎handlebars.js实用教程——目录
  2. SeekBar 圆角问题
  3. Ubuntu 编译安装 Linux 4.0.5 内核,并修复 vmware 网络内核模块编译错误
  4. Java定位CPU使用高问题--转载
  5. Android学习笔记之ExecutorService线程池的应用....
  6. javascript基础知识拾遗
  7. php 解决和避免form表单重复提交的方法
  8. bzoj 1026 [SCOI2009]windy数 数位dp
  9. DATASNAP多表提交之事务控制之通用方法
  10. destoon程序中qq号码,手机号,msn必选项实现方法
  11. HttpURLConnection getInputStream异常的解决
  12. COM编程_第一讲_深入COM框架以及实现简单的COM
  13. Web Mining and Big Data 公开课学习笔记 ---lecture0
  14. BZOJ_4198_[Noi2015]荷马史诗_huffman实现
  15. redsi一主两从三哨兵
  16. 20180307-Xen、KVM、VMware、hyper-v等虚拟化技术的比较
  17. Django内置模板标签
  18. python中的字符串编码问题——1.理解编码和解码问题
  19. Spring部署报错:Could not open ServletContext resource [/db.properties]
  20. 【Java面试题】15 String s="Hello"; s=s+“world!”;这两行代码执行后,原始的String对象中的内容到底变了没有?String与StringBuffer的超详细讲解!!!!!

热门文章

  1. 002.Ceph安装部署
  2. hadoop安装过程中出现的错误
  3. html 知识点
  4. 如何突破Ue4材质编辑器没有Pass的概念
  5. LOJ.6074.[2017山东一轮集训Day6]子序列(DP 矩阵乘法)
  6. BZOJ.5289.[AHOI/HNOI2018]排列(贪心 heap)
  7. Java笔记(十)堆与优先级队列
  8. scrapy中间件
  9. [P3452][POI2007]BIU-Offices (BFS)
  10. fastjson 使用教程