mysql 索引列为Null的走不走索引及null在统计时的问题
要尽可能地把字段定义为 NOT NULL,即使应用程序无须保存 NULL(没有值),也有许多表包含了可空列(Nullable Column)
这仅仅是因为它为默认选项。除非真的要保存 NULL,否则就把列定义为 NOT NULLMySQL难以优化引用了可空列的查询,它会使索引、索引统计和值更加复杂。
可空列需要更多的储存空间,还需要在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在统计时的问题相关推荐
- mysql null 走索引_mysql 索引列为Null的走不走索引及null在统计时的问题
要尽可能地把字段定义为 NOT NULL,即使应用程序无须保存 NULL(没有值),也有许多表包含了可空列(Nullable Column) 这仅仅是因为它为默认选项.除非真的要保存 NULL,否则就 ...
- MySql中的like和in走不走索引
今天我们来实际操作一下 首先我们创建一个用户表进行测试 Like 在email字段上加一个索引来测试Like关键字 我们先来复习一下Like语句的几种写法 往大的方向说Like语句由两种写法,分别时% ...
- MySQL的in条件走不走索引
答案是:看in后面跟的条件和扫描行的比例 目录 准备条件 鉴定过程 编写查询sql语句,查看执行计划: 这里吧in后面的数据范围变大: 这里测试把后面的条件: a.b换成 demo02.demo03 ...
- 作为唯一索引_Mysql什么情况下不走索引?
本文基于Mysql5.7版本和InnoDB存储引擎. 1.InnoDB索引组织表 在InnoDB引擎中,表都是按照主键顺序组织存放的,这种存放方式的表称为索引组织表.InnoDB存储引擎中的表,都有主 ...
- 查询没有走索引_关于MySQL种的in函数到底走不走索引、我和同事差点大打出手!...
" 我是小羊同学,一个兢兢业业的程序员" 背景:有一天同事突然问我为什么加了in查询就突然变慢了.小羊脱口而出:"in不走索引!" 于是就炸开了锅:in不走索引 ...
- mysql in 索引_关于MySQL种的in函数到底走不走索引、我和同事差点大打出手!
" 我是小羊同学,一个兢兢业业的程序员" 背景:有一天同事突然问我为什么加了in查询就突然变慢了.小羊脱口而出:"in不走索引!" 于是就炸开了锅:in不走索引 ...
- mysql的in走不走索引?
结论 mysql的in关键字不一定走索引. 个人猜测跟传入的元素个数和索引字段离散程度有关. 验证过程 -- mysql版本 select version(); -- 5.7.28-log-- 增加索 ...
- 对于LIMITE,Mysql优化器导致的有时候不走索引而是走全表查询
使用Mysql官方数据库sakila作示例 首先查看actor表内索引 有一个主键索引(聚簇索引)和一个last_name字段的二级索引 这里我是想走聚簇索引找出第一条id,当然这里 ...
- MYSQL 中 OR 走不走索引
目录 添加a.b独立索引 添加a.b组合索引 新建表test01,字段:id.a.b.c 添加a.b独立索引 EXPLAIN SELECT * FROM test01 WHERE a = 1 OR b ...
最新文章
- Django源码分析8:单元测试test命令浅析
- js实现横向跑马灯效果
- C#委托的异步调用[转]
- 软件工程——成品展示
- 颠覆网站 C/S 模式,没有服务器的网站会怎样?
- 数据库得事务控制详解,什么是事务回滚详解,通俗易懂
- Windows+Linux 双系统安装教程
- Gephi从入门到精通
- 智慧工地、智慧建筑、项目GIS、工程信息化协同管理平台、BIM一体化项目管理平台、工程进度管理、计划进度、施工模拟、BIM视图、模型管理、质量管理、安全管理、施工管理、文档管理、建筑施工、工程展板
- Windows 10注册表损坏该如何修复?
- 计算机网络技术文档心得,计算机网络技术学习心得体会.docx
- Linux内核UDP收包为什么效率低?能做什么优化?
- 从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。
- RichTextBox 增加行间距
- 使用 python 写出诗一样的代码 (一)
- Ubuntu ROS 安装
- 设置页眉页脚--分节符
- win10找不到打印机_WIN10打印机共享设置
- python 动态类型语言,Python 3.7.0 面向对象的动态类型语言
- tf.nn.nce_loss分析
热门文章
- 完整学习git三 查看暂存区目录树 git diff
- Redis 通配符查找及批量删除key
- coreseek实时索引更新之增量索引
- jQuery入门[1]-构造函数
- 通用Makefile模板
- java 送参数_关于java:如何以编程方式发送带参数的HTTP请求?
- PAT 乙级 1036. 跟奥巴马一起编程(15) Java版
- jdbc executebatch 非事务_jdbc技术
- 查询group_by 与 order by
- zabbix3.0 监控mysql服务器性能实现过程