init测试数据:
CREATE TABLE `test_range` (
`aa` int(11) ,
`bb` varchar(60) ,
`cc` datetime ,
`dd` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
KEY `cc` (`cc`,`aa`)
) ENGINE=InnoDB
##create table test_range(aa int not null, bb varchar(60) not null, cc datetime not null, dd TIMESTAMP)
##alter table test_range add key(cc,aa)
drop procedure if exists data_init_test1;
create procedure data_init_test1()
begin
DECLARE start_flag int;
DECLARE date_flag date;
DECLARE list_length int;
set start_flag = 0;
set date_flag = CURDATE();
set list_length = 10000;
while start_flag < list_length DO
insert into test_range(aa, bb, cc) values(start_flag, start_flag, date_flag);
set date_flag = date_add(date_flag, INTERVAL 1 day);
set start_flag = start_flag + 1;
end while;
end;
##call data_init_test1()
####MySQL5.1测试
int类型aa ,未加not null,
datetime类型cc, 未加not null
desc select * from test_range where cc = '2014-08-14' and aa = 25;
explain的结果:
key: cc (这个是复合索引(cc,aa))
key_len: 14
也就是cc这个复合索引里,cc索引是9个字节(比datetime的4个字节增长一倍+1个字节 ) aa索引是5个字节(比int类型增长1个字节)
##把两个字段加上not null后
alter table test_range change aa aa int not null
alter table test_range change cc cc int not null
desc select * from test_range where cc = '2014-08-14' and aa = 25;
explain的结果:
key: cc (这个是复合索引(cc,aa))
key_len: 12
也就是跟base类型一样的长度,记得某些类型,或者某些情况下,它的长度会增大N倍的,所以。。。注意了。
####MySQL5.5测试
效果一样,db本身没优化。
所以坚决用not null default xxx
并且有一点需要注意。datetime从null改成not null 后,它原来的数据格式会转成年的。
如果给值datetime to 一个整型,默认模式下,它会初始成年份。
线上要注意。
另外: