要尽可能地把字段定义为 NOT NULL,即使应用程序无须保存 NULL(没有值),也有许多表包含了可空列(Nullable Column)
这仅仅是因为它为默认选项。除非真的要保存 NULL,否则就把列定义为 NOT NULL

MySQL难以优化引用了可空列的查询,它会使索引、索引统计和值更加复杂。
可空列需要更多的储存空间,还需要在MySQL内部进行特殊处理。当可空列被索引的时候,
每条记录都需要一个额外的字节,还可能导致 MyISAM 中固定大小的索引(例如一个整数列上的索引)变成可变大小的索引。
即使要在表中储存「没有值」的字段,还是有可能不使用 NULL 的,考虑使用 0、特殊值或空字符串来代替它。
把 NULL 列改为 NOT NULL 带来的性能提升很小,所以除非确定它引入了问题,否则就不要把它当作优先的优化措施。
然后,如果计划对列进行索引,就要尽量避免把它设置为可空,虽然在mysql里 Null值的列也是走索引的

 mysql> SELECT 1 IS NULL, 1 IS NOT NULL;
+-----------+---------------+
| 1 IS NULL | 1 IS NOT NULL |
+-----------+---------------+
|         0 |             1 |
+-----------+---------------+
1 row in setmysql> SELECT 0 IS NULL, 0 IS NOT NULL, '' IS NULL, '' IS NOT NULL;
+-----------+---------------+------------+----------------+
| 0 IS NULL | 0 IS NOT NULL | '' IS NULL | '' IS NOT NULL |
+-----------+---------------+------------+----------------+
|         0 |             1 |          0 |              1 |
+-----------+---------------+------------+----------------+

测试

CREATE TABLE `test_null` (`id` int(11) DEFAULT NULL,`mark` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;create procedure test_null(in num int)
BEGIN
DECLARE i int;
set i=1;
while (i<num)
DO if mod(i,10)!=0 then insert into test_null values (i,concat('aaa',i));elseinsert into test_null values (null,concat('aaa',i));end if;
set i=i+1;
END while;
END;call test_null(10000);

mysql> select count(*) from test_null;
+----------+
| count(*) |
+----------+
|     9999 |
+----------+
没加任何索引时
mysql> explain SELECT * from test_null WHERE id is null;
+----+-------------+-----------+------------+------+---------------+------+---------+------+-------+----------+-------------+
| id | select_type | table     | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |
+----+-------------+-----------+------------+------+---------------+------+---------+------+-------+----------+-------------+
|  1 | SIMPLE      | test_null | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 10105 |       10 | Using where |
+----+-------------+-----------+------------+------+---------------+------+---------+------+-------+----------+-------------+
在id上加普通索引
create index idx_test_null on test_null(id);
mysql> explain SELECT * from test_null WHERE id is null;
+----+-------------+-----------+------------+------+---------------+---------------+---------+-------+------+----------+-----------------------+
| id | select_type | table     | partitions | type | possible_keys | key           | key_len | ref   | rows | filtered | Extra                 |
+----+-------------+-----------+------------+------+---------------+---------------+---------+-------+------+----------+-----------------------+
|  1 | SIMPLE      | test_null | NULL       | ref  | idx_test_null | idx_test_null | 5       | const |  999 |      100 | Using index condition |
+----+-------------+-----------+------------+------+---------------+---------------+---------+-------+------+----------+-----------------------+
null值也是走索引的

 null在count统计时时的问题

create table test (id int,val int);
INSERT INTO `test` VALUES ('1', '11');
INSERT INTO `test` VALUES ('1', '111');
INSERT INTO `test` VALUES ('2', '2');
INSERT INTO `test` VALUES ('2', '22');
INSERT INTO `test` VALUES ('2', '222');

1条语句统计id=1,id=2的个数

一般错误写法

select count(id=1) ,count(id=2) from test;

mysql> select count(id=1) ,count(id=2) from test;
+-------------+-------------+
| count(id=1) | count(id=2) |
+-------------+-------------+
|           5 |           5 |
+-------------+-------------+

需要注意count只不会统计null的列,0的会统计

mysql> select 1 or null as or1,1 and null as and1 ,0 and null as and0 ,0 or null as null0;
+------+------+------+-------+
| or1  | and1 | and0 | null0 |
+------+------+------+-------+
|    1 | NULL |    0 |  NULL |
+------+------+------+-------+

mysql> select id=1 ,id=2 from test;
+------+------+
| id=1 | id=2 |
+------+------+
|    1 |    0 |
|    1 |    0 |
|    0 |    1 |
|    0 |    1 |
|    0 |    1 |
+------+------+

要把0值变为null,count时不计算即可

mysql> select count(id=1) ,count(id=2) from test;
+-------------+-------------+
| count(id=1) | count(id=2) |
+-------------+-------------+
|           5 |           5 |
+-------------+-------------+
mysql> select id=1 or null,id=2 or null from test;
+--------------+--------------+
| id=1 or null | id=2 or null |
+--------------+--------------+
|            1 |         NULL |
|            1 |         NULL |
|         NULL |            1 |
|         NULL |            1 |
|         NULL |            1 |
+--------------+--------------+

所以正确的写法是

mysql> select count(id=1 or null),count(id=2 or null) from test;
+---------------------+---------------------+
| count(id=1 or null) | count(id=2 or null) |
+---------------------+---------------------+
|                   2 |                   3 |
+---------------------+---------------------+
1 row in set (0.00 sec)

select id,count(id) from test where id in(1,2) GROUP BY id

常数与null的运算

DROP TABLE IF EXISTS `test1`;
CREATE TABLE `test1` (`id` int(11) DEFAULT NULL,`a` int(11) DEFAULT NULL,`b` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;-- ----------------------------
-- Records of test1
-- ----------------------------
INSERT INTO `test1` VALUES ('1', '5', '1');
INSERT INTO `test1` VALUES ('2', '6', null);
INSERT INTO `test1` VALUES ('3', '4', '2');
INSERT INTO `test1` VALUES ('4', '7', null);
INSERT INTO `test1` VALUES ('5', null, null);

查询 id,a-b的数量(剩余计算)

错误写法

mysql> SELECT id ,(a-b) as remain from test1;
+------+--------+
| id   | remain |
+------+--------+
|    1 |      4 |
|    2 |   NULL |
|    3 |      2 |
|    4 |   NULL |
|    5 |   NULL |
+------+--------+

正确写法

mysql> SELECT id ,(IFNULL(a,0)-IFNULL(b,0)) as remain  from test1;
+------+--------+
| id   | remain |
+------+--------+
|    1 |      4 |
|    2 |      6 |
|    3 |      2 |
|    4 |      7 |
|    5 |      0 |
+------+--------+

转载于:https://www.cnblogs.com/HKUI/p/8546891.html

mysql 索引列为Null的走不走索引及null在统计时的问题相关推荐

  1. mysql null 走索引_mysql 索引列为Null的走不走索引及null在统计时的问题

    要尽可能地把字段定义为 NOT NULL,即使应用程序无须保存 NULL(没有值),也有许多表包含了可空列(Nullable Column) 这仅仅是因为它为默认选项.除非真的要保存 NULL,否则就 ...

  2. MySql中的like和in走不走索引

    今天我们来实际操作一下 首先我们创建一个用户表进行测试 Like 在email字段上加一个索引来测试Like关键字 我们先来复习一下Like语句的几种写法 往大的方向说Like语句由两种写法,分别时% ...

  3. MySQL的in条件走不走索引

    答案是:看in后面跟的条件和扫描行的比例 目录 准备条件 鉴定过程 编写查询sql语句,查看执行计划: 这里吧in后面的数据范围变大: 这里测试把后面的条件: a.b换成 demo02.demo03 ...

  4. 作为唯一索引_Mysql什么情况下不走索引?

    本文基于Mysql5.7版本和InnoDB存储引擎. 1.InnoDB索引组织表 在InnoDB引擎中,表都是按照主键顺序组织存放的,这种存放方式的表称为索引组织表.InnoDB存储引擎中的表,都有主 ...

  5. 查询没有走索引_关于MySQL种的in函数到底走不走索引、我和同事差点大打出手!...

    " 我是小羊同学,一个兢兢业业的程序员" 背景:有一天同事突然问我为什么加了in查询就突然变慢了.小羊脱口而出:"in不走索引!" 于是就炸开了锅:in不走索引 ...

  6. mysql in 索引_关于MySQL种的in函数到底走不走索引、我和同事差点大打出手!

    " 我是小羊同学,一个兢兢业业的程序员" 背景:有一天同事突然问我为什么加了in查询就突然变慢了.小羊脱口而出:"in不走索引!" 于是就炸开了锅:in不走索引 ...

  7. mysql的in走不走索引?

    结论 mysql的in关键字不一定走索引. 个人猜测跟传入的元素个数和索引字段离散程度有关. 验证过程 -- mysql版本 select version(); -- 5.7.28-log-- 增加索 ...

  8. 对于LIMITE,Mysql优化器导致的有时候不走索引而是走全表查询

    使用Mysql官方数据库sakila作示例 首先查看actor表内索引 有一个主键索引(聚簇索引)和一个last_name字段的二级索引          这里我是想走聚簇索引找出第一条id,当然这里 ...

  9. MYSQL 中 OR 走不走索引

    目录 添加a.b独立索引 添加a.b组合索引 新建表test01,字段:id.a.b.c 添加a.b独立索引 EXPLAIN SELECT * FROM test01 WHERE a = 1 OR b ...

最新文章

  1. Django源码分析8:单元测试test命令浅析
  2. js实现横向跑马灯效果
  3. C#委托的异步调用[转]
  4. 软件工程——成品展示
  5. 颠覆网站 C/S 模式,没有服务器的网站会怎样?
  6. 数据库得事务控制详解,什么是事务回滚详解,通俗易懂
  7. Windows+Linux 双系统安装教程
  8. Gephi从入门到精通
  9. 智慧工地、智慧建筑、项目GIS、工程信息化协同管理平台、BIM一体化项目管理平台、工程进度管理、计划进度、施工模拟、BIM视图、模型管理、质量管理、安全管理、施工管理、文档管理、建筑施工、工程展板
  10. Windows 10注册表损坏该如何修复?
  11. 计算机网络技术文档心得,计算机网络技术学习心得体会.docx
  12. Linux内核UDP收包为什么效率低?能做什么优化?
  13. 从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。
  14. RichTextBox 增加行间距
  15. 使用 python 写出诗一样的代码 (一)
  16. Ubuntu ROS 安装
  17. 设置页眉页脚--分节符
  18. win10找不到打印机_WIN10打印机共享设置
  19. python 动态类型语言,Python 3.7.0 面向对象的动态类型语言
  20. tf.nn.nce_loss分析

热门文章

  1. 完整学习git三 查看暂存区目录树 git diff
  2. Redis 通配符查找及批量删除key
  3. coreseek实时索引更新之增量索引
  4. jQuery入门[1]-构造函数
  5. 通用Makefile模板
  6. java 送参数_关于java:如何以编程方式发送带参数的HTTP请求?
  7. PAT 乙级 1036. 跟奥巴马一起编程(15) Java版
  8. jdbc executebatch 非事务_jdbc技术
  9. 查询group_by 与 order by
  10. zabbix3.0 监控mysql服务器性能实现过程