欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

非复合多列索引实战

程序员文章站 2024-03-16 18:45:46
...

mysql之explain分析表

#建表

test : id,name,age,addr,qq
test_copy  : id,name,age,addr,qq

CREATE TABLE `test` (
  `id` bigint(12) NOT NULL AUTO_INCREMENT,
  `name` varchar(12) DEFAULT NULL,
  `age` int(4) DEFAULT NULL,
  `addr` varchar(23) DEFAULT NULL,
  `qq` varchar(12) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`) USING BTREE,
  KEY `idx_age` (`age`) USING BTREE,
  KEY `idx_addr` (`addr`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
CREATE TABLE `test_copy` (
  `id` bigint(12) NOT NULL AUTO_INCREMENT,
  `name` varchar(12) DEFAULT NULL,
  `age` int(4) DEFAULT NULL,
  `addr` varchar(23) DEFAULT NULL,
  `qq` varchar(12) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

#建test表索引
非唯一性索引【NORMAL】name,age,addr
索引类型
非复合多列索引实战
索引方式
非复合多列索引实战
false:表示索引失效
true:表示索引有效

以***释内容的含义:是否有效 索引类型 索引列
以下内容直接复制到Navicat的新建查询测试即可

#OR 只要有or索引就无效

EXPLAIN SELECT * from test where age = 1 or name=""  #fasle
EXPLAIN SELECT age from test where age = 1 or name="" #fasle

#LIKE

EXPLAIN SELECT * from test where name like "%a" #fasle
EXPLAIN SELECT name from test where name like "%a" #true index idx_name
EXPLAIN SELECT * from test where name like "%a%" #fasle
EXPLAIN SELECT name from test where name like "%a%" #true index idx_name
EXPLAIN SELECT * from test where name like "a%" #true  range idx_name

#单个字段

EXPLAIN SELECT * from test where age<>1  #fasle
EXPLAIN SELECT * from test where age = 1  #true ref idx_age
EXPLAIN SELECT age from test where age<>1  #true index idx_age
EXPLAIN SELECT * from test where age <= 1  #true range  idx_age
EXPLAIN SELECT * from test where age  BETWEEN 1 and 2  #true range  idx_age

#多个字段

EXPLAIN SELECT * from test where age<>1 and name="a" #true ref idx_name ,顺序无关 
EXPLAIN SELECT * from test where age<1 and name="a" #true ref idx_name,顺序无关

#ORDER BY

EXPLAIN SELECT * from test where age>1  ORDER BY name #fasle
EXPLAIN SELECT * from test where 1=1 BETWEEN 1 and 2  ORDER BY name #fasle
EXPLAIN SELECT * from test where age>1 and name="a" ORDER BY name #true ref idx_name
EXPLAIN SELECT * from test where age=1 and name="a" ORDER BY name #true ref idx_name

#多表查询

EXPLAIN SELECT * from test t,test_copy te where t.id=te.id #true eq_ref  primary
EXPLAIN SELECT * from test t,test_copy te where t.name=te.name #true ref  idx_name
EXPLAIN SELECT * from test t,test_copy te where te.name=t.name #true ref  idx_name
EXPLAIN SELECT * from test t LEFT JOIN test_copy te on t.name=te.name #true ref idx_name

#SUBQUERY

EXPLAIN SELECT * from test where id IN(select id from test where age<>1)#true unique_subquery PRIMARY
EXPLAIN SELECT * from test where id IN(select id from test where age>1)#true unique_subquery PRIMARY
EXPLAIN SELECT * from test where name IN(select name from test where age>1)#true index_subquery idx_name

总结

select *索引失效不代表select column索引也失效
select *索引有效则select column索引肯定有效

select * from user where name="" #索引有效
select name from user where name="" #索引有效

例如

EXPLAIN select * from user where name<>"" #索引无效

可以改善为

EXPLAIN select * from user u,(select name from user where name<>"") u1 where 
u.name=u1.name #使用连接查询使索引起效

此种多列索引一般不推荐,数据库开销大,多列索引请使用复合索引,请看下篇复合索引实战

复合索引实战