前些时候在学习MySQL 索引的时候,看很多人的博客说查询条件中是 is null ,is not null ,<> 的情况, 索引会失效,我本人没试,索引信以为真,后来别人提醒下,自己亲自测试了一下, 果然它是走索引的,所以不能盲目相信网上的博客,在此记录一下。
我这里有一张杆塔信息表,表结构信息如图,
CREATE TABLE `src_tower_info` (
`tower_id` varchar(50) NOT NULL COMMENT '杆塔ID',
`tower_name` varchar(100) DEFAULT NULL COMMENT '杆塔名称',
`tower_code` int(11) DEFAULT NULL COMMENT '杆塔号',
`line_id` varchar(50) DEFAULT NULL COMMENT '线路ID',
`region` varchar(10) DEFAULT NULL COMMENT '地区',
`parent_region` varchar(10) DEFAULT NULL COMMENT '父地区',
`maintainer` varchar(100) DEFAULT NULL COMMENT '供电公司',
`altitude` varchar(50) DEFAULT NULL COMMENT '海拔',
`height` varchar(20) DEFAULT NULL COMMENT '高度',
`terrain` varchar(50) DEFAULT NULL COMMENT '地形',
`stationmap_1` double(20,10) DEFAULT NULL COMMENT '经度',
`stationmap_2` double(20,10) DEFAULT NULL COMMENT '纬度',
`dilei` varchar(10) DEFAULT NULL COMMENT '地类',
`whdj` varchar(10) DEFAULT NULL COMMENT '危害等级',
`design_ice_thickness` varchar(20) DEFAULT NULL COMMENT '设计覆冰厚度',
`design_wind_speed` varchar(20) DEFAULT NULL COMMENT '设计风速',
`jyzinfo` varchar(10) DEFAULT NULL COMMENT '绝缘子信息',
`padianbiju` varchar(20) DEFAULT NULL COMMENT '爬电比距',
`loopnum` varchar(50) DEFAULT NULL COMMENT '回路数',
`tower_property` varchar(20) DEFAULT NULL COMMENT '杆塔类型(耐张,直线)',
`installwave` varchar(10) DEFAULT NULL COMMENT '是否有防舞动装置(是,否)',
`resistance_design_value` varchar(50) DEFAULT NULL COMMENT '接地电阻设计值',
`zblx` int(5) DEFAULT NULL COMMENT '植被类型',
`windspan` varchar(50) DEFAULT NULL COMMENT '水平档距',
`is_valid` bit(1) DEFAULT NULL COMMENT '是否有效(0:有效;1:无效)',
`invalid` varchar(400) DEFAULT NULL COMMENT '字段有、无效标识(0:有效;1:无效)',
`invalid_model` varchar(40) DEFAULT NULL COMMENT '数据无效的模型(以","分隔)',
`create_at` timestamp NULL DEFAULT NULL COMMENT '天鹰库入库时间',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`tower_id`),
UNIQUE KEY `line_tower_id__unique` (`line_id`,`tower_id`) USING BTREE,
KEY `index_tower_name` (`tower_name`) USING BTREE,
KEY `index_tower_code` (`tower_code`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='(台账)杆塔信息表';
表中建有一个名字为 index_tower_code 的二级索引,tower_code 字段可以为空。我们本次就是用这个字段来做实验。
首先我们查询tower_code 为空的数据一共有多少条,
SELECT COUNT(tower_id) FROM src_tower_info where tower_code is NULL
我们用explain 查询此SQL的执行过程。
执行过程显示 此SQL查询使用了index_tower_code 这个索引。
同理,测试了is not null , <> 也使用了索引。
MySQL中索引一般以B+树数据结构保存数据,二级索引叶子节点中保存的是主键值,索引按从小到大的顺序排列。当二级索引列为null时,节点值最小,位于最左侧,查询为null的的时候从最左侧取直到第一个不为null的节点返回。