精华内容
下载资源
问答
  • 要尽可能地把字段定义 NOT NULL,即使应用程序无须保存 NULL(没有值),也有许多表包含了可空列(Nullable Column)这仅仅是因为它默认选项。除非真的要保存 NULL,否则就把列定义 NOT NULLMySQL难以优化引用了可...

    要尽可能地把字段定义为 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

    DOif mod(i,10)!=0 then

    insert into test_null values (i,concat('aaa',i));else

    insert into test_null values (null,concat('aaa',i));end if;set i=i+1;END while;END;

    call test_null(10000);

    mysql> select count(*) fromtest_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 ontest_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) fromtest;+-------------+-------------+

    | 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 asnull0;+------+------+------+-------+

    | or1 | and1 | and0 | null0 |

    +------+------+------+-------+

    | 1 | NULL | 0 | NULL |

    +------+------+------+-------+

    mysql> select id=1 ,id=2 fromtest;+------+------+

    | 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) fromtest;+-------------+-------------+

    | count(id=1) | count(id=2) |

    +-------------+-------------+

    | 5 | 5 |

    +-------------+-------------+

    mysql> select id=1 or null,id=2 or null fromtest;+--------------+--------------+

    | 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) fromtest;+---------------------+---------------------+

    | 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 fromtest1;+------+--------+

    | id | remain |

    +------+--------+

    | 1 | 4 |

    | 2 | NULL |

    | 3 | 2 |

    | 4 | NULL |

    | 5 | NULL |

    +------+--------+

    正确写法

    mysql> SELECT id ,(IFNULL(a,0)-IFNULL(b,0)) as remain fromtest1;+------+--------+

    | id | remain |

    +------+--------+

    | 1 | 4 |

    | 2 | 6 |

    | 3 | 2 |

    | 4 | 7 |

    | 5 | 0 |

    +------+--------+

    展开全文
  • mysql 数据库字段为null时 token_app加了索引 1. SELECT * FROM `user` WHERE token_app='xxx' SELECT * FROM `user` WHERE token_app is null 上面的都会走索引 2. SELECT * FROM `user` WHERE token_app is not ...

    总结:

    mysql 数据库字段为null时 token_app加了索引 
    1.
    SELECT * FROM `user` WHERE token_app='xxx'
    SELECT * FROM `user` WHERE token_app is null
    上面的都会走索引

    2.
    SELECT * FROM `user` WHERE token_app is not null
    is not null不会走索引

    3.数据过少时会全表扫描 mysql的优化器决定的  如果全表扫描比走索引快,就会全表扫描

    展开全文
  • 首先创建测试表,建表及数据写入语句如下:use muke; /* 使用muke这个database */drop table if exists t1; /* 如果表t1存在则删除表t1 */CREATE TABLE `t1` ( /* 创建表t1 */`id` int(11) NOT NULL AUTO_INCRE...

    首先创建测试表,建表及数据写入语句如下:use muke; /* 使用muke这个database */

    drop table if exists t1; /* 如果表t1存在则删除表t1 */

    CREATE TABLE `t1` ( /* 创建表t1 */

    `id` int(11) NOT NULL AUTO_INCREMENT,

    `a` varchar(20) DEFAULT NULL,

    `b` int(20) DEFAULT NULL,

    `c` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,

    PRIMARY KEY (`id`),

    KEY `idx_a` (`a`) USING BTREE,

    KEY `idx_b` (`b`) USING BTREE,

    KEY `idx_c` (`c`) USING BTREE

    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

    drop procedure if exists insert_t1; /* 如果存在存储过程insert_t1,则删除 */

    delimiter ;;

    create procedure insert_t1() /* 创建存储过程insert_t1 */

    begin

    declare i int; /* 声明变量i */

    set i=1; /* 设置i的初始值为1 */

    while(i<=10000)do /* 对满足i<=10000的值进行while循环 */

    insert into t1(a,b) values(i,i); /* 写入表t1中a、b两个字段,值都为i当前的值 */

    set i=i+1; /* 将i加1 */

    end while;

    end;;

    delimiter ;

    call insert_t1(); /* 运行存储过程insert_t1 */

    update t1 set c = '2019-05-22 00:00:00'; /* 更新表t1的c字段,值都为'2019-05-22 00:00:00' */

    update t1 set c = '2019-05-21 00:00:00' where id=10000; /* 将id为10000的行的c字段改为与其它行都不一样的数据,以便后面实验使用 */

    1. 函数操作

    1.1 不走索引的原SQL:select * from t1 where date(c) ='2019-05-21';

    1.2 优化后走索引的SQL:select * from t1 where c>='2019-05-21 00:00:00' and c<='2019-05-21 23:59:59';

    2. 隐式转换

    2.1 不走索引的原SQL:select user_name,tele_phone from user_info where tele_phone =11111111111; /* SQL 1 */

    2.2 优化后走索引的SQL:select user_name,tele_phone from user_info where tele_phone ='11111111111';

    3. 模糊查询

    3.1 不走索引的原SQL:select * from t1 where a like '%1111%';

    3.2 优化后走索引的SQL(结果不一定准确):select * from t1 where a like '1111%';

    3.3 或者使用搜索服务器 (如果条件只知道中间的值,需要模糊查询去查,那就建议使用ElasticSearch、SPHINX或者其它搜索服务器。)

    4. 范围查询

    4.1 不走索引的原SQL:select * from t1 where b>=1 and b <=2000;

    4.2 优化后走索引的SQL:select * from t1 where b>=1 and b <=1000;

    select * from t1 where b>=1001 and b <=2000;

    5. 计算操作

    5.1 不走索引的原SQL:select * from t1 where b-1 =1000;

    5.2 优化后走索引的SQL:select * from t1 where b =1000 + 1;

    展开全文
  • 面试:xxx是索引字段,那么mysql 中where xxx is null 会使用到索引吗? 答案:如果索引字段设置的是可以空的情况下,是可以使用到索引的。 验证: CREATE TABLE `department` ( `id` int(10) NOT NULL COMMENT ...

    面试:xxx是索引字段,那么mysql 中where xxx is null 会使用到索引吗?
    答案:如果索引字段设置的是可以为空的情况下,是可以使用到索引的。

    验证:

    
    
    CREATE TABLE `department` (
    `id`  int(10) NOT NULL COMMENT 'id' ,
    `depname`  varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci ***NOT NULL*** COMMENT '部门名称' ,
    `depparentid`  varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci ***NULL*** DEFAULT NULL COMMENT '父ID' ,
    `depdesc`  varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '描述' ,
    PRIMARY KEY (`id`),
    UNIQUE INDEX `indx_deptName` (`depname`) USING BTREE ,
    UNIQUE INDEX `index_deptDesc` (`depdesc`) USING BTREE 
    )
    ENGINE=InnoDB
    DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
    ROW_FORMAT=COMPACT
    ;
    

    department 表中 depname 字段设置为不为空;depdesc 设置为可以为空。

    SELECT VERSION();-- 5.5.27

    -- depdesc 字段设置为可以为 NULL  
    -- type ref  索引没有失效
    EXPLAIN  SELECT * FROM department t WHERE t.depdesc is NULL; 
    -- type ALL 索引失效
    EXPLAIN  SELECT * FROM department t WHERE t.depdesc is NOT NULL; 
    
    -- depname 字段设置为不能为null 
    -- type 为null 根本没有使用到索引
    EXPLAIN SELECT * FROM department t where t.depname is NULL;
    -- type ALL 索引失效
    EXPLAIN SELECT * FROM department t where t.depname is NOT NULL;
    
    一句话总结:只有字段设置为 可以为空的时候,使用 is null 才可以使用到索引,其他情况使用不到索引。
    
    
    展开全文
  • mysql字段为null不能使用!= 数据库表中某一字段(mark)默认值为NULL,进行where语句查询时mark!=‘xxxx’,并能将字段为NULL的数据查询出来。 1、mysql中空值占空间,null值占空间。 2、当使用 IS NOT NULL ...
  • 相信很多用了MySQL很久的人,对这两个字段属性的概念还不是很清楚,一般会有以下疑问:我字段类型是not null,为什么我可以插入空值为毛not null的效率比null高判断字段不为空的时候,到底要...
  •  Be sure to check the MySQL product documentation for specific information.” 知道是不是说的你这种情况。我用5.0.67,好像not null约束也怎么管用。 【 在 dulang6 (雨) 的大作中提到: ...
  • Mysql字段属性应该尽量设置not null

    千次阅读 2021-01-19 12:34:53
    除非你有一个很特别的原因去使用 NULL 值,你应该总是让你的字段保持 NOT NULL。这看起来好像有点争议,请往下看。所谓的NULL就是什么都没有,连\0都没有,\0在字符串中是结束符,但是在物理内存是占空间的,等于一...
  • heaven参考文章MySQL 字段属性应该尽量设置 NOT NULL除非你有一个很特别的原因去使用 NULL 值,你应该总是让你的字段保持 NOT NULL。这看起来好像有点争议,请往下看。1、首先,我们要搞清楚空值 "" 和 NULL 的...
  • 这种说法是错的:”MySql 中是能用 null索引的,任何包含null值的列都将不会被包含在索引中“我们做个实验如下,可以看到b字段建有索引,b 字段中有 null,但是select count(*) from a group by b用了b上的覆盖...
  • 相信很多用了MySQL很久的人,对这两个字段属性的概念还不是很清楚,一般会有以下疑问:我字段类型是not null,为什么我可以插入空值为什么not null的效率比null高判断字段不为空的时候,到底要 select * from table ...
  • 其实 从 个人的角度来看,, 都无所谓,,为了麻烦,有时候 都是 默认可以 null 的 。 但是看了一些 文章,说 如果 字段 加了索引...注意:MySQL字段尽量避免NULL,应该指定列为NOT NULL,除非你想存储NULL。在MyS...
  • 一.首先看一个我在某公众号看到的一个关于数据库优化的举措二....先列出结论:where子句中使用上述对null的判断,如果判断的列设置了索引,那就可以使用到索引三.测试:1.建表1 CREATE TABLE`test_null_index` (2 `i...
  • mysql 唯一索引null.md

    2021-01-21 09:17:09
    mysql 的唯一索引要求所有参与的列都能够 null 值,如果唯一索引中的任何一个元素含有 null 值,则唯一约束将起作用。示例代码create table tb (a int,b int,c int,unique index (a,b,c));insert into tb(a,b,...
  • MySQL字段为null

    2021-07-15 10:11:26
    1.我们都知道,MySQL建议我们在创建表字段的时候,默认值尽可能的使用 非null,一个好处是提升查询速度避免无法使用索引优化,另一个就是使用中容易产生不必要的问题; 2.当某一个字段,其中有的值为null时,如果我们使用了...
  • 正式开始之前,我们先来看下 MySQL 服务器的配置和版本号信息,如下图所示: -- 查看SQL 配置信息 SHOW VARIABLES; -- 使用Like 模糊查询 查看全量日志相关的配置 SHOW VARIABLES LIKE "general_log%"; “兵马...
  • 什么会有许多表的字段设置为NULL?开发中常用的建表工具创建表时字段默认可以 NULL。开发人员能正确区分NULL和 NOTNULL的区别,以为默认NULL 可以节省空间。...
  • 1.新建一张表,并且加上索引 CREATE TABLE `people` ( `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id', `age` int unsigned NOT NULL DEFAULT '5' COMMENT '年龄', `name` varchar(30) COLLATE utf8mb4_...
  • 我们常常从关于MySQL的各种技术博客、书籍上面看到这样一句话:“能在字段上使用函数,否则就不会走索引”。那么这句话的依据是什么呢? 本文就围绕“能在字段上使用函数,否则就不会走索引”这句话来展开分析。...
  • 经常用mysql的人可能会遇到下面几种情况:1、我字段类型是not null,为什么我可以插入空值2、为什么not null的效率比null高3、判断字段不为空的时候,到底要用select * from table where column <> ''还是要用...
  • 数据库建表时,对于一些可填可不填的字段,我们应该尽量把它设置 NOT NULL。这种做法即可以提高性能,又可以在很大程度上避免空指针类的问题,好处颇多。1.节省空间NULL 列需要更多的存储空间:需要一个额外字节...
  • 测试环境:数据库:MySQL5.7.25数据库引擎:InnoDB连接工具:Navicat Premium首先,创建数据库,并创建测试表 test:DROP TABLE IF EXISTS `test`;CREATE TABLE `test` (`id` int(11) NOT NULL COMMENT 'ID',`name` ...
  • 所以我们在数据库设计时不要让字段的默认值为NULL。在很多库表设计规范、某某军规的文章中,是不是经常会看到类似这样的内容。小编也经常看到这样的内容,并且在编写规范的时候,准备也把这一条加进去。但在按部就班...
  • MySQLNULL和空值的区别,索引列是否可空值或null发布时间:2018-07-25 18:02,浏览次数:298, 标签:MySQLNULL在创建表的时候尽量把字段的默认值设置成 notnull,除非你想存储null;因为在mysql中为null的的字段...
  • 后来查看表结构才发现,原来用来做关联的字段是一个varchar类型的字段,而联接的另一张表中的字段类型却是bigint,结果造成了类型的匹配,以致于索引失效。如果要想索引起效,最直接的办法就是将两张表的...
  • 查数据库发现表的email字段加了唯一索引,最多有一条空或者其他值的数据 解决办法:唯一索引可在索引列插入多次null email可以有多条email为null的记录,将冲突的字段设置为null,解决 在sql server中,唯一索引...
  • MySQL索引失效的几种情况汇总

    千次阅读 2021-01-18 20:19:54
    索引不存储null值更准确的说,单列索引不存储null值,复合索引不存储全为null的值。索引不能存储Null,所以对这列采用is null条件时,因为索引上根本没Null值,不能利用到索引,只能全表扫描。什么索引列不能存...
  • 二、Mysql(二) 原文参考:http://www.cnblogs.com/wupeiqi/articles/5713323.html 还有一个是课件,看着也像博客,但知道是谁的 内置函数 触发器 存储过程 索引 与p ... 一、Java JUC简介 在 Java 5.0 提供了 java...
  • 一.背景 今天在测试过程中发现有数据重复的现象...2.1 首先创建一个 user 表,指定 user_name + address 联合唯一索引 CREATE TABLE `t_user` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 154,114
精华内容 61,645
关键字:

mysql字段为null不走索引

mysql 订阅