如果保函null字段是数字 is null 和is not null都不走索引
如果保函null字段是字符 is null不走索引 和is not null会走索引
字符类型可以默认'' 数字类型可以默认0
1、数据库为5.6.0版本测试
mysql> select @@version;
+------------+
| @@version |
+------------+
| 5.6.10-log |
+------------+
1 row in set (0.00 sec)
mysql>
mysql> create table test_innodb (id int(11) unsigned NOT NULL primary key AUTO_INCREMENT,name varchar(100)) engine=innodb;
Query OK, 0 rows affected (0.16 sec)
mysql> show create table test_innodb\G
*************************** 1. row ***************************
Table: test_innodb
Create Table: CREATE TABLE `test_innodb` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> insert into test_innodb(name) values('hlf'),('huanglf');
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> show create table test_innodb\G
*************************** 1. row ***************************
Table: test_innodb
Create Table: CREATE TABLE `test_innodb` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> optimize table test_innodb;
+------------------+----------+----------+-------------------------------------------------------------------+
| Table | Op | Msg_type | Msg_text |
+------------------+----------+----------+-------------------------------------------------------------------+
| test.test_innodb | optimize | note | Table does not support optimize, doing recreate + analyze instead |
| test.test_innodb | optimize | status | OK |
+------------------+----------+----------+-------------------------------------------------------------------+
2 rows in set (0.30 sec)
mysql> show create table test_innodb\G
*************************** 1. row ***************************
Table: test_innodb
Create Table: CREATE TABLE `test_innodb` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql>
#####################################
增加列并测试null字段索引
mysql> alter table test_INNODB ADD COLUMN numb int(8) default null;
Query OK, 0 rows affected (0.55 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql>
mysql>
mysql> alter table test_INNODB drop COLUMN numb ;
Query OK, 0 rows affected (0.55 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table test_innodb;
+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| test_innodb | CREATE TABLE `test_innodb` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 |
+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> alter table test_INNODB ADD COLUMN numb int(8) default null,add column addr varchar(100) default null;
Query OK, 0 rows affected (0.55 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table test_innodb;
+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| test_innodb | CREATE TABLE `test_innodb` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL,
`numb` int(8) DEFAULT NULL,
`addr` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 |
+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql>
mysql> alter table test_innodb add index idx_numb(numb);
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql>
mysql> alter table test_innodb add index idx_addr(addr);
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table test_innodb;
+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| test_innodb | CREATE TABLE `test_innodb` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL,
`numb` int(8) DEFAULT NULL,
`addr` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_numb` (`numb`),
KEY `idx_addr` (`addr`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 |
+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql>
mysql> insert into test_innodb(name,numb,addr) values('huanglingfei',80,'chengdu'),('wanger'),('mazhi','guizhou'),('zhangsan',60);
ERROR 1136 (21S01): Column count doesn't match value count at row 2
mysql>
mysql> insert into test_innodb(name,numb,addr) values('huanglingfei',80,'chengdu');
Query OK, 1 row affected (0.00 sec)
mysql>
mysql>
mysql>
mysql>
mysql> insert into test_innodb(name) values('wanger');
Query OK, 1 row affected (0.00 sec)
mysql>
插入错误类型是出现警告并把插字符串自动替换为数字0
mysql> insert into test_innodb(name,numb) values('mazhi','guizhou'),('zhangsan',60);
Query OK, 2 rows affected, 1 warning (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 1
mysql> select * from test_innodb;
+----+--------------+------+---------+
| id | name | numb | addr |
+----+--------------+------+---------+
| 1 | hlf | NULL | NULL |
| 2 | huanglf | NULL | NULL |
| 3 | huanglingfei | 80 | chengdu |
| 4 | wanger | NULL | NULL |
| 5 | mazhi | 0 | NULL |
| 6 | zhangsan | 60 | NULL |
+----+--------------+------+---------+
6 rows in set (0.00 sec)
mysql>
mysql> explain select * from test_innodb where id in(3,4,5);
+----+-------------+-------------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | test_innodb | range | PRIMARY | PRIMARY | 4 | NULL | 3 | Using where |
+----+-------------+-------------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql> select * from test_innodb where id in(3,4,5);
+----+--------------+------+---------+
| id | name | numb | addr |
+----+--------------+------+---------+
| 3 | huanglingfei | 80 | chengdu |
| 4 | wanger | NULL | NULL |
| 5 | mazhi | 0 | NULL |
+----+--------------+------+---------+
3 rows in set (0.00 sec)
mysql>
数字字段
mysql>
mysql> explain select * from test_innodb where numb=80;
+----+-------------+-------------+------+---------------+----------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+------+---------------+----------+---------+-------+------+-------+
| 1 | SIMPLE | test_innodb | ref | idx_numb | idx_numb | 5 | const | 1 | NULL |
+----+-------------+-------------+------+---------------+----------+---------+-------+------+-------+
1 row in set (0.00 sec)
mysql>
mysql> explain select * from test_innodb where numb is not null;
+----+-------------+-------------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | test_innodb | ALL | idx_numb | NULL | NULL | NULL | 6 | Using where |
+----+-------------+-------------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql>
mysql>
mysql> select * from test_innodb where numb is not null;
+----+--------------+------+---------+
| id | name | numb | addr |
+----+--------------+------+---------+
| 3 | huanglingfei | 80 | chengdu |
| 5 | mazhi | 0 | NULL |
| 6 | zhangsan | 60 | NULL |
+----+--------------+------+---------+
3 rows in set (0.00 sec)
mysql>
mysql> explain select * from test_innodb where numb is null;
+----+-------------+-------------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | test_innodb | ALL | idx_numb | NULL | NULL | NULL | 6 | Using where |
+----+-------------+-------------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql>
mysql> select * from test_innodb where numb is null;
+----+---------+------+------+
| id | name | numb | addr |
+----+---------+------+------+
| 1 | hlf | NULL | NULL |
| 2 | huanglf | NULL | NULL |
| 4 | wanger | NULL | NULL |
+----+---------+------+------+
3 rows in set (0.00 sec)
mysql>
字符字段 is not null 居然走了索引
mysql> explain select * from test_innodb where addr='chengdu';
+----+-------------+-------------+------+---------------+----------+---------+-------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+------+---------------+----------+---------+-------+------+-----------------------+
| 1 | SIMPLE | test_innodb | ref | idx_addr | idx_addr | 303 | const | 1 | Using index condition |
+----+-------------+-------------+------+---------------+----------+---------+-------+------+-----------------------+
1 row in set (0.00 sec)
mysql>
mysql> select * from test_innodb where addr='chengdu';
+----+--------------+------+---------+
| id | name | numb | addr |
+----+--------------+------+---------+
| 3 | huanglingfei | 80 | chengdu |
+----+--------------+------+---------+
1 row in set (0.00 sec)
mysql>
mysql> explain select * from test_innodb where addr is null;
+----+-------------+-------------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | test_innodb | ALL | idx_addr | NULL | NULL | NULL | 6 | Using where |
+----+-------------+-------------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql>
mysql>
mysql>
mysql> select * from test_innodb where addr is null;
+----+----------+------+------+
| id | name | numb | addr |
+----+----------+------+------+
| 1 | hlf | NULL | NULL |
| 2 | huanglf | NULL | NULL |
| 4 | wanger | NULL | NULL |
| 5 | mazhi | 0 | NULL |
| 6 | zhangsan | 60 | NULL |
+----+----------+------+------+
5 rows in set (0.00 sec)
mysql>
mysql> explain select * from test_innodb where addr is not null;
+----+-------------+-------------+-------+---------------+----------+---------+------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+-------+---------------+----------+---------+------+------+-----------------------+
| 1 | SIMPLE | test_innodb | range | idx_addr | idx_addr | 303 | NULL | 1 | Using index condition |
+----+-------------+-------------+-------+---------------+----------+---------+------+------+-----------------------+
1 row in set (0.00 sec)
mysql>
mysql>
mysql> select * from test_innodb where addr is not null;
+----+--------------+------+---------+
| id | name | numb | addr |
+----+--------------+------+---------+
| 3 | huanglingfei | 80 | chengdu |
+----+--------------+------+---------+
1 row in set (0.00 sec)
mysql>
2、数据库为5.1.7版本测试:
mysql> select @@version;
+------------+
| @@version |
+------------+
| 5.1.73-log |
+------------+
1 row in set (0.00 sec)
mysql>
create table test_innodb (id int(11) unsigned NOT NULL primary key AUTO_INCREMENT,
name varchar(100),
numb int(8) default null,
addr varchar(100) default null,
key idx_numb (numb),
key idx_addr (addr)
) engine=innodb;
mysql> create table test_innodb (id int(11) unsigned NOT NULL primary key AUTO_INCREMENT,
-> name varchar(100),
-> numb int(8) default null,
-> addr varchar(100) default null,
-> key idx_numb (numb),
-> key idx_addr (addr)
-> ) engine=innodb;
Query OK, 0 rows affected (0.25 sec)
mysql>
insert into test_innodb(name) values('hlf'),('huanglf');
insert into test_innodb(name,numb,addr) values('huanglingfei',80,'chengdu');
insert into test_innodb(name) values('wanger');
insert into test_innodb(name,numb) values('mazhi','guizhou'),('zhangsan',60);
mysql> insert into test_innodb(name) values('hlf'),('huanglf');
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> insert into test_innodb(name,numb,addr) values('huanglingfei',80,'chengdu');
Query OK, 1 row affected (0.00 sec)
mysql> insert into test_innodb(name) values('wanger');
Query OK, 1 row affected (0.00 sec)
mysql> insert into test_innodb(name,numb) values('mazhi','guizhou'),('zhangsan',60);
ERROR 1366 (HY000): Incorrect integer value: 'guizhou' for column 'numb' at row 1
mysql>
mysql> insert into test_innodb(name,numb) values('mazhi','0'),('zhangsan',60);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from test_innodb;
+----+--------------+------+---------+
| id | name | numb | addr |
+----+--------------+------+---------+
| 1 | hlf | NULL | NULL |
| 2 | huanglf | NULL | NULL |
| 3 | huanglingfei | 80 | chengdu |
| 4 | wanger | NULL | NULL |
| 5 | mazhi | 0 | NULL |
| 6 | zhangsan | 60 | NULL |
+----+--------------+------+---------+
6 rows in set (0.00 sec)
mysql>
从结果看字符字段is not null 也是会走索引的
mysql> explain select * from test_innodb where numb=80;
+----+-------------+-------------+------+---------------+----------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+------+---------------+----------+---------+-------+------+-------------+
| 1 | SIMPLE | test_innodb | ref | idx_numb | idx_numb | 5 | const | 1 | Using where |
+----+-------------+-------------+------+---------------+----------+---------+-------+------+-------------+
1 row in set (0.00 sec)
mysql>
mysql> explain select * from test_innodb where numb is null;
+----+-------------+-------------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | test_innodb | ALL | idx_numb | NULL | NULL | NULL | 6 | Using where |
+----+-------------+-------------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql> explain select * from test_innodb where numb is not null;
+----+-------------+-------------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | test_innodb | ALL | idx_numb | NULL | NULL | NULL | 6 | Using where |
+----+-------------+-------------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql>
mysql> explain select * from test_innodb where addr is null;
+----+-------------+-------------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | test_innodb | ALL | idx_addr | NULL | NULL | NULL | 6 | Using where |
+----+-------------+-------------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql>
mysql>
mysql> explain select * from test_innodb where addr is not null;
+----+-------------+-------------+-------+---------------+----------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+-------+---------------+----------+---------+------+------+-------------+
| 1 | SIMPLE | test_innodb | range | idx_addr | idx_addr | 303 | NULL | 1 | Using where |
+----+-------------+-------------+-------+---------------+----------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql>