3、#普通索引:primary key - 可以创建联合索引 - 可以创建前缀索引 #查看一张表的索引方法: 查看表结构的方法: root@localhost:(none) > desc mysql.user; ---- Key #key列的就是索引 ---- PRI PRI 建表语句的方法查看: root@localhost:(none) > show create table mysql.user; PRIMARY KEY (`Host`,`User`) 查看一张表里面都有哪些索引 show index from 表名; root@localhost:(none) > show index from mysql.user;
root@localhost:student > desc stu5; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int(11) | NO | | 0 | | | name | varchar(10) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 1、添加普通索引 #给name字段添加普通索引(里面的值可以为空,也可以重复,就是为了查询的速度快) alter table 表名 add index 索引名(字段);
root@localhost:student > alter table stu5 add index idx_name(name); root@localhost:student > desc stu5; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int(11) | NO | | 0 | | | name | varchar(10) | YES | MUL | NULL | | +-------+-------------+------+-----+---------+-------+ root@localhost:student > show index from stu5;
2、删除普通索引 root@localhost:student > alter table stu5 drop index idx_name;
root@localhost:student > show index from stu5; #查看表里面有哪些索引,发现是空的,删除成功 Empty set (0.00 sec)
#创建相亲表 create table xiangqin(id int comment '序号', name varchar(10) comment '姓名', gender enum('0','1') comment '性别', high int comment '身高', weight int comment '体重', body varchar(10) comment '身材', salary int) comment '收入';
1)、#假设用户最关注的是: 性别:gender 收入:salary 身材:body
2)、#根据用户喜好创建联合索引创建联合索引 root@localhost:student > alter table xiangqin add index idx_all(gender,salary,body); 如果创建的时候,把body放第一个,用户查询的时候就不走索引,这个索引等于没建 查看: root@localhost:student > show index from xiangqin;
创建联合索引+前缀索引 root@localhost:student > alter table xiangqin add index idex_all(gender,salary(4),body);
root@localhost:student > desc xiangqin; | gender | enum('0','1') | YES | MUL | NULL | #只看到排序的第一个有索引 root@localhost:student > show index from xiangqin; #可以看全
例: 当:a.女生 and b.身高 and c.体重 and d.身材好 index(a,b,c) 特点:前缀生效特性 a,ab,ac,abc,abcd 可以走索引或部分走索引 b bc bcd cd c d ba ... 不走索引 只要a不在前面,就不走索引
2、#唯一索引创建联合索引 先删除上次创建的索引 root@localhost:student > alter table xiangqin drop index idx_all; 字段的数据不能重复
root@localhost:student > alter table xiangqin add unique key uni_all(gender,salary,body);
3、#主键索引创建联合索引 先删除上次创建的索引 root@localhost:student > alter table xiangqin drop index uni_all;
创建主键索引 root@localhost:student > alter table xiangqin add primary key(gender,salary,body);
root@localhost:student > desc xiangqing #3个都显示
1 2 3
分析慢查询语句,需要开启慢查询日志,他会把慢的sql语句记录进去
mysql执行慢,可能和扫描有关
Mysql数据扫描
1、全表扫描
1 2 3 4 5 6 7 8 9 10 11
#什么情况下出现全表扫描 情况1、select * from tb1; 情况2、select 查询数据时,where条件接的字段,没有创建索引 (不走索引,就是全表扫描)
root@localhost:student > explain select * from world.city; +----+-------------+-------+------+---------------+------+---------+------+------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | +----+-------------+-------+------+---------------+------+---------+------+------+ | 1 | SIMPLE | city | ALL | NULL | NULL | NULL | NULL | 4188 | +----+-------------+-------+------+---------------+------+---------+------+------+ #可以看到type类型是ALL 扫描的行数是4188行
1、# index:全索引扫描(最慢,和全表扫描没什么区别) root@localhost:student > show index from world.city; 它做了普通索引的,只查countrycode这一列
root@localhost:student > select countrycode from world.city; #explain就是分析sql语句 root@localhost:student > explain select countrycode from world.city; +----+-------------+-------+-------+---------------+-------------+---------+------+------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | +----+-------------+-------+-------+---------------+-------------+---------+------+------+ | 1 | SIMPLE | city | index | NULL | CountryCode | 3 | NULL | 4188 | +----+-------------+-------+-------+---------------+-------------+---------+------+------+ #可以看到type类型是index 扫描的行数是4188行
2、# range:范围查询并创建了索引 只要能达到rang级别,就是OK的 如果想把range优化到system的级别,是不能实现的,system级别只能主键索引能到底 root@localhost:student > select * from world.city where population<1000; root@localhost:student > explain select * from world.city where population<1000; +----+-------------+-------+-------+----------------+----------------+---------+------+------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | +----+-------------+-------+-------+----------------+----------------+---------+------+------+ | 1 | SIMPLE | city | range | idx_population | idx_population | 4 | NULL | 11 | +----+-------------+-------+-------+----------------+----------------+---------+------+------+ #可以看到type类型是range 扫描的行数是11行
#这两个效率一样 root@localhost:student > explain select * from world.city where countrycode='CHN' or countrycode='USA'; root@localhost:student > explain select * from world.city where countrycode in ('CHN','USA'); +----+-------------+-------+-------+---------------+-------------+---------+------+------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | +----+-------------+-------+-------+---------------+-------------+---------+------+------+ | 1 | SIMPLE | city | range | CountryCode | CountryCode | 3 | NULL | 637 | +----+-------------+-------+-------+---------------+-------------+---------+------+------+ #可以看到type类型是range 扫描的行数是637行
#优化到ref级别 root@localhost:student > explain select * from world.city where countrycode='CHN' union all select * from world.city where countrycode='USA'; +----+--------------+------------+------+---------------+-------------+---------+-------+------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | +----+--------------+------------+------+---------------+-------------+---------+-------+------+ | 1 | PRIMARY | city | ref | CountryCode | CountryCode | 3 | const | 363 | | 2 | UNION | city | ref | CountryCode | CountryCode | 3 | const | 274 | | NULL | UNION RESULT | <union1,2> | ALL | NULL | NULL | NULL | NULL | NULL +----+--------------+------------+------+---------------+-------------+---------+-------+------+ #可以看到type类型是ref 扫描的行数是分开的
3、# ref:联合查询、普通索引的精确查询 联合查询 root@localhost:student > explain select * from world.city where countrycode='CHN' union all select * from world.city where countrycode='USA';