索引是什么?
索引(Index)是帮助MySQL高效获取数据的数据结构。索引的本质就是数据结构。你也可以简单的理解为“排好序的快速查找数据结构。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引。
创建一个索引
create INDEX idx_test_name on idx_test(name);
创建复合索引
create INDEX idx_test_name on idx_test(name,code);
如果表创建完成后添加索引
ALTER table tableName ADD INDEX indexName(columnName)
查看表中有那些索引
show index from idx_test
删除一个索引
drop INDEX idx_sharecfg_createTime ON tbl_agent_sharecfg
索引的优势:
1. 提高数据检索的效率,降低数据库的io成本
2. 通过索引对数据进行排序,降低数据排序的成本,降低了CPU的消耗。
索引的劣势:
1. 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。
2. 索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。
3. 当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。
哪些情况需要索引:
1. 主键自动建立唯一索引
2. 频繁作为查询条件的字段应该创建索引
3. 查询中与其它表关联的字段,外键关系建立索引
4. 频繁更新的字段不合适创建索引,因为每次更新不单单是更新了记录还会更新索引
5. where 条件里用不到的字段不创建索引
6. 单键/组合索引的选择问题,在高并发的情况下倾向创建组合索引
7. 查询中排序的字段,排序字段若通过索引去访问将大大提高排序的速度
8. 查询中统计或者分组字段
哪些情况不需要索引:
1. 表记录太少
2. 经常增删改的表,因为提高了查询速度,同时却会降低更新表的速度。
3. 数据重复且分布平均的表字段,因此应该只为最经常查询和最经常排序的数据建立索引,注意,如果某个数据列包含许 多重复的内容,为它建立索引就没有太大的实际效果。
索引的分类:
1. 单值索引:即一个索引只包含单个列,一个表可以有多个单列索引
2. 唯一索引:索引列的值必须唯一,但允许有空值
3. 复合索引:及一个索引包含多个列
4. 基本语法:
创建:方式一:CREATE INDEX index_name ON table(column(length))
方式二: ALTER TABLE table_name ADD INDEX index_name ON (column(length))
MySQL常见的瓶颈:
1. CPU在饱和的时候一般发生在数据装入内存或者从磁盘上读取数据的时候
2. IO磁盘I/O瓶颈发生在装入数据远大于内存容量的时候
3. 服务器硬件的性能瓶颈:top,free,iostat和vmstat来查看系统的性能状态
Explain是什么:
使用Explain 关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的,分析你的查询语句或是表结构的性能瓶颈。
Explain能够做什么:
- 表的读取顺序
- 数据读取操作的操作类型
- 哪些索引可以使用
- 哪些索引被实际使用
- 表之间的引用
- 每张表有多少行被优化器查询
- 在explain的帮助下,就知道什么时候该给表添加索引,以使用索引来查找记录从而让select 运行更快。
Explain字段和详解:
Expain出来的信息有10列,分别是id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra.
一、 id
这里的ID不是主键,而是是SQL执行的顺序的标识, 根据ID的大小SQL从大到小的执行
- id相同时,执行顺序由上至下
- 如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行
- id如果相同,可以认为是一组,从上往下顺序执行;在所有组中,id值越大,优先级越高,越先执行
二、select_type
表示查询中每个select子句的类型
- SIMPLE(简单SELECT,不使用UNION或子查询等)
- PRIMARY(查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY)
- UNION(UNION中的第二个或后面的SELECT语句)
- DEPENDENT UNION(UNION中的第二个或后面的SELECT语句,取决于外面的查询)
- UNION RESULT(UNION的结果)
- SUBQUERY(子查询中的第一个SELECT)
- DEPENDENT SUBQUERY(子查询中的第一个SELECT,取决于外面的查询)
- DERIVED(派生表的SELECT, FROM子句的子查询)
- UNCACHEABLE SUBQUERY(一个子查询的结果不能被缓存,必须重新评估外链接的第一行)
三、table
显示这一行的数据是关于哪张表的,有时不是真实的表名字,看到的是derivedx(x是个数字,我的理解是第几步执行的结果)
mysql> explain select * from (select * from ( select * from t1 where id=1) a) b;
四、type
表示MySQL在表中找到所需行的方式,又称“访问类型”。
常用的类型有: ALL, index, range, ref, eq_ref, const, system, NULL(从左到右,性能从差到好)
1. ALL:Full Table Scan,MySQL将遍历全表以找到匹配的行
2. Index: Full Index Scan,index与ALL区别为index类型只遍历索引树
3. range: 只检索给定范围的行,使用一个索引来选择行
4. ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值
5. eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是 多表连接中使用primary key或者 unique key作为关联条件
6. const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where 列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用 system
7. NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过
单独索引查找完成。
五、possible_keys
指出MySQL能使用哪个索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用,该列完全独立于EXPLAIN输出所示的表的次序。这意味着在possible_keys中的某些键实际上不能按生成的表次序使用。
如果该列是NULL,则没有相关的索引。在这种情况下,可以通过检查WHERE子句看是否它引用某些列或适合索引的列来提高你的查询性能。如果是这样,创造一个适当的索引并且再次用EXPLAIN检查查询。
六、Key
key列显示MySQL实际决定使用的键(索引)
如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。
七、key_len
表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度(key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的) 不损失精确性的情况下,长度越短越好。
八、ref
表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值
九、rows
表示MySQL根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数
十、Extra
该列包含MySQL解决查询的详细信息,有以下几种情况:
1. Using where:列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候,表示mysql服务器将在存储引擎检索行后再进行过滤
2. Using temporary:表示MySQL需要使用临时表来存储结果集,常见于排序和分组查询 【出现这个不好,要优化SQL】
3. Using filesort:MySQL中无法利用索引完成的排序操作称为“文件排序”【出现这个不好,要优化SQL】
4. Using join buffer:改值强调了在获取连接条件时没有使用索引,并且需要连接缓冲区来存储中间结果。如果出现了这个值,那应该注意,根据查询的具体情况可能需要添加索引来改进能。
5. Impossible where:这个值强调了where语句会导致没有符合条件的行。
6. Select tables optimized away: 该值意味着仅通过使用索引,优化器可能仅从聚合函数结果中返回一行
7. 补充:Using index 【出现这个SQL比较理想】