mysiam引擎
create table 表名(
id int not null auto_increment primary key,
name varchar(32) not null,
age int
) engine=myisam default charset=utf8;
聚簇引擎
create table 表名(
id int not null auto_increment primary key,
name varchar(32) not null,
age int
) engine=innodb default charset=utf8;
两种索引的文件对比
开发中,一般使用 innodb 引擎,支持事务,行级锁,外键等特点
在mysql5.5之后,所有默认引擎也是 innodb
可以找到 mysql的安装目录,比如:/usr/local/mysql/data/userdb
常见不同引擎的表,生成的文件也不一样
比如 big 这张表,是基于 innodb 引擎的
对于表 t2 是 myisam 引擎的话
我们后续用的 innodb ,都是聚簇索引
表结构示例
create table `users` (
`id` int(11) not null auto_increment,
`name` varchar(32) default null,
`email` varchar(64) default null,
`password` varchar(64) default null,
`age` int(11) default null,
primary key (`id`), --- 主键索引
unique key `big_unique_email` (`email`), --- 唯一索引
index `ix_name_pwd` (`name`, `password`), --- 联合索引
) engine=InnoDB default charset=utf8;
查询示例
select * from big where id=5;
select * from big where id>5;
select * from big where email='xxxx@qq.com';
select * from big where name='xxx';
select * from big where name='sss' and password='ssdd';
1 )类型不一致场景
select * from users where name = 123; -- 不会命中索引
select * from users where email = 123; -- 不会命中索引
-- 下面用主键
select * from users where id='123'; -- 会命中索引
2 )使用不等于
select * from users where name != 'xxxx'; -- 不会命中索引
select * from users where email != 'xxxx@qq.com'; -- 不会命中索引
-- 主键
select * from users where id != 123; -- 不会命中索引
3 )使用 or
select * from users where id = 123 or password = 'x'; -- 不会命中 这里后面联合索引中只用了一个
select * from users where name = 'xx' or password = 'y'; -- 不会命中 用 or 将联合索引拆成了两个
-- 下面会命中
select * from users where id = 10 or password='xx' and name='yy'; -- 命中 这里 or 前后都是索引
4 )使用排序
select * from users order by name asc; -- 未命中
select * from users order by name desc; -- 未命中
-- 主键会命中
select * from users order by id desc; -- 会命中
5 )like 模糊匹配时
select * from users where name like '%xxx' -- 不会命中
select * from users where name like '_xxx' -- 不会命中
select * from users where name like 'xx%xx' -- 不会命中
-- 通配符在最后,会命中
select * from users where name like "xxxx%" -- 命中
select * from users where name like "xxxx_" -- 命中
6 )使用函数
select * from users where reverse(name) = 'xxxx'; --- 不会命中
-- 特别的
select * from users where name = reverse('abc') -- 会命中
7 )联合索引
如果是联合索引,最遵循最左前缀原则
如果联合索引为 (name, password)
name and passsword
命中name
命中password
不会命中name or password
不会命中最左边用可以命中,用or连接则不能
explain sql语句
1 )使用
explain select * from users
2 )解析 type
基于输出表格字段中的 type 来看,它是一个重要的性能指标
详解如下
select * from users
全部扫描select * from users limit 1;
这里特别,遇到 limit 结束后不再扫描explain select id from users;
explain select name from users;
explain select * from users where id > 10;
explain select * from users where id in (1,2,3);
explain select * from users where id = 10 or name='xxx'
select * from users where name = 'xxx'
explain select article.title, users.id from article left join users on user.id = article.uid
explain select * from users where id = 123;
这里是主键explain select * from users email = 'xxxx@qq.com
唯一索引explain select * from (select * from users where id=1 limit 1) as A
;综合以上,一般来说,性能在 RANGE 及其以上,性能算是 OK的
当然,这不是最终结果,只是初步的评价,和最终效率一定会有差异
3 )其他字段
explain select * from users where id = 1;
100, 这里只读了一行,返回结果也是1行explain select * from big where password = 'xxx'
10, 读取了10行,返回了1行,注意,这里 xxx的 password在第10行Using index
表示mysql将使用覆盖索引,以避免访问表。不要把覆盖索引和index的访问类型弄混了Using where
Using temporary
Using filesort
Range checked foreachrecord(index map: N)