1.1索引
MUL 辅助索引
PRI 主键(聚集索引)
UNI 唯一键
1.2索引的操作管理
建立 索引
mysql> alter table t100w add index idx_k2(k2);
Query OK, 0 rows affected (6.11 sec)
查询索引
mysql> show index from t100w;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| t100w | 1 | idx_k2 | 1 | k2 | A | 3826 | NULL | NULL | YES | BTREE | | |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)
mysql> desc t100w;
+-------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+-------------------+-----------------------------+
| id | int(11) | YES | | NULL | |
| num | int(11) | YES | | NULL | |
| k1 | char(2) | YES | | NULL | |
| k2 | char(4) | YES | MUL | NULL | |
| dt | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------+-----------+------+-----+-------------------+-----------------------------+
5 rows in set (0.00 sec)
创建唯一索引
mysql>alter table t100w add unique index index_k1(k1);
前缀索引只能设置给字符串类型的列
mysql> alter table city add index idx_name(name(3));
Query OK, 0 rows affected (0.10 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> alter table city drop index idx_name;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
;
创建联合索引
mysql> alter table city add index idx_n_p(countrycode,population);
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show index from city
-> ;
+-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| city | 0 | PRIMARY | 1 | ID | A | 4188 | NULL | NULL | | BTREE | | |
| city | 1 | CountryCode | 1 | CountryCode | A | 232 | NULL | NULL | | BTREE | | |
| city | 1 | idx_n_p | 1 | CountryCode | A | 232 | NULL | NULL | | BTREE | | |
| city | 1 | idx_n_p | 2 | Population | A | 4052 | NULL | NULL | | BTREE | | |
+-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
4 rows in set (0.00 sec)
2.执行计划
2.1作用
上线新的查询语句之前,进行提前预警性能较差的语句(提前预估语句性能)
在出现性能问题时可以找到合理的解决思路
2.2执行计划获取
desc和explain都可以获取执行计划(部分),结果一样
mysql> desc select * from city where name='ShangHai';
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+
| 1 | SIMPLE | city | NULL | ref | idx_name | idx_name | 35 | const | 1 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
重要的列:
table: 显示从哪个表查询,单表无所谓,多表会有作用
type: 索引的应用级别(应用类型)
possible_key 可能会使用到的索引
key 实际用到的索引
key_len 联合索引的覆盖程度(针对联合索引,可以判断出用的索引)
rows 覆盖的行数(查询的行数,越少越好)
Extra 额外的信息
2.3关键信息介绍
type:ref
级别
1>ALL:全表扫描,遍历,不走索引
出现ALL的情况:(1)没建立索引
(2)建了索引不走
2>Index:全索引扫描
3>range:索引范围扫描
4>ref:辅助索引等值查询
5>eq_ref:多表连接查询时,on的条件列是唯一索引或主键
6>const,system:主键或唯一键的等值查询
级别:从上往下,性能依次变好
ALL:全表扫描,遍历,不走索引
出现ALL的情况:(1)没建立索引
(2)建了索引不走
六种不走索引的情况:
mysql> desc select * from t100w where k2 != 'aaa'; 辅助索引出现!=才会出现all
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| 1 | SIMPLE | t100w | NULL | ALL | idx_k2 | NULL | NULL | NULL | 888567 | 100.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> desc select * from t100w where k2 like '%xy%';
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| 1 | SIMPLE | t100w | NULL | ALL | NULL | NULL | NULL | NULL | 888567 | 11.11 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> desc select k1 from t100w;
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------+
| 1 | SIMPLE | t100w | NULL | ALL | NULL | NULL | NULL | NULL | 888567 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------+
1 row in set, 1 warning (0.00 sec)
mysql> desc select * from t100w;
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------+
| 1 | SIMPLE | t100w | NULL | ALL | NULL | NULL | NULL | NULL | 888567 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------+
1 row in set, 1 warning (0.00 sec)
总结:(1) select * from 不会走索引
(2)select 非索引列 from 不会走索引
(3)!=不等于在辅助索引时是all在聚集索引是range
(4)%a 模糊匹配在前时是ALL,在后面的时候会显示range
Index:全索引扫描
mysql> desc select k2 from t100w;
+----+-------------+-------+------------+-------+---------------+--------+---------+------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+--------+---------+------+--------+----------+-------------+
| 1 | SIMPLE | t100w | NULL | index | NULL | idx_k2 | 17 | NULL | 888567 | 100.00 | Using index |
+----+-------------+-------+------------+-------+---------------+--------+---------+------+--------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
取索引列的所有数据
range:索引范围扫描
辅助索引:< > <= >= like 这类可以接受
in or 这类尽量避免
主键:!= 出现在主键列则会走range
mysql> desc select * from world.city where countrycode like 'C%'
mysql> desc select * from world.city where id!=3000;
mysql> desc select * from world.city where id>3000;
mysql> desc select * from world.city where countrycode in ('CHN','USA');
改写为:
desc
select * from world.city where countrycode='CHN'
union all
select * from world.city where countrycode='USA';
ref:辅助索引等值查询
mysql> desc select * from city where countrycode='CHN';
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
| 1 | SIMPLE | city | NULL | ref | CountryCode | CountryCode | 3 | const | 363 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
eq_ref:多表连接查询时,on的条件列是唯一索引或主键
mysql> desc select a.name,b.name ,b.surfacearea
-> from city as a
-> join country as b
-> on a.countrycode=b.code
-> where a.population <100;
+----+-------------+-------+------------+--------+---------------+---------+---------+---------------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+--------+---------------+---------+---------+---------------------+------+----------+-------------+
| 1 | SIMPLE | a | NULL | ALL | CountryCode | NULL | NULL | NULL | 4188 | 33.33 | Using where |
| 1 | SIMPLE | b | NULL | eq_ref | PRIMARY | PRIMARY | 3 | world.a.CountryCode | 1 | 100.00 | NULL |
+----+-------------+-------+------------+--------+---------------+---------+---------+---------------------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)
const,system:主键或唯一键的等值查询
mysql> desc select * from city where id='10';
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| 1 | SIMPLE | city | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | NULL |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
Extra:Null 额外的信息
+---------------------------------------+
| Extra |
+---------------------------------------+
| Using index condition; Using filesort |
+---------------------------------------+
Using filesort解决方法:
mysql> desc select * from city where countrycode='CHN' order by population;
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+---------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+---------------------------------------+
| 1 | SIMPLE | city | NULL | ref | CountryCode | CountryCode | 3 | const | 363 | 100.00 | Using index condition; Using filesort |
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+---------------------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> alter table city add index idx_pop_cou(countrycode,population);
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc select * from city where countrycode='CHN' order by population;
+----+-------------+-------+------------+------+-------------------------+-------------+---------+-------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+-------------------------+-------------+---------+-------+------+----------+-----------------------+
| 1 | SIMPLE | city | NULL | ref | CountryCode,idx_pop_cou | idx_pop_cou | 3 | const | 363 | 100.00 | Using index condition |
+----+-------------+-------+------------+------+-------------------------+-------------+---------+-------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
设置联合索引
3.Explain(desc)使用场景(面试题)
1.MySQL出现性能问题,总结有两种情况
(1)应急性的慢,突然夯住
应急处理:数据库夯住(卡了,资源耗尽)
处理过程:
1.show proesslist;获取到导致数据库夯住的语句
2.explain分析SQL语句的执行计划,有没有走索引,索引的类型情况
3.建索引,改语句
(2)一段时间慢(持续性)
1.记录慢日志,slowlog,分析slowlog
2.explain,分析SQL的执行计划,有没有走索引,索引的类型情况
3.建索引,改语句
4.索引应用规范
业务
1.产品的功能
2.用户的行为
“热”查询语句--->较慢--->slowlog
“热数据”
4.1建立索引的原则(DBA运维规范)
4.1.0说明
为了使索引的使用效率更高,在创建索引时,必须考虑在哪些字段上创建索引和创建什么类型的索引。那么索引设计原则又是怎样的?
4.1.1(必须的) 建表时一定要有主键,一般是个无关列
略.回顾一下,聚集索引结构.
4.1.2选择唯一性索引
唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录。
4.1.3
当有where group by order by 时,要建立联合索引
4.10*********关于联合索引************
(1)where A, group by B. order by c ---------->(A,,B,C)
(2)只有where A B C
1>都是等值的情况下(5.5版本以后无关索引顺序,都可以走索引),
但是,我们需要把唯一值最多的一列放到最左边
2>如果有不等值的查询,例如以下情况
select where A= and B> and C=
索引顺序是ACB/CAB,语句改写为ACB/CAB,AC的位置取决于里面的唯一值的多少