// 索引是高效获取数据的数据结构
// 索引结构主要有B+TREE与HASH
// 索引分类:主键索引,唯一索引,常规索引,全文索引
// 根据索引结构分类分为:聚集索引,二级索引
// 索引基础操作
// 创建索引
// 一个索引关联单个字段成为单列索引,关联多个字段则成为联合索引或者是组合索引
// create [unique | fulltext] index index_name on table_name(udex_col_name,....);
// 查看索引
// show index from table_name;
// 删除索引
// drop index index_name on table_name;
// ---------------------------------------------------------------------------------------------
// sql性能分析
// 第一种方法
// 查看数据库的insert,update,delete,select访问频次
// Com后面有七个下划线
// show global status like 'Com_______';
// 第二种方法
// 慢查询日志
// 通过慢查询日志定为查询较慢的sql语句,进行定点优化
// 所有执行时间超过指参数比如默认为10秒的所有sql语句的日志,针对于单个sql语句操作时间
// 慢查询默认关闭需要在(/etc/my.cnf)中配置
// #开启慢查询
// slow_query_log = 1
// #设置慢查询日志实践为2秒,sql语句执行时间超过2秒,则为慢查询
// long_query_time = 2
// 第三种方法
// profile详情
// show profile可以展示时间都耗费到了哪里
// 通过以下操作可以查看当前mysql是否支持profile操作:
// select @@have_profiling;
// 我们可以通过set语句在session/global级别开启profiling
// set profiling = 1;
// 查看每一条sql的耗时基本情况
// show profiles;
// 查看指定query_id的sql语句各个阶段的好事情况
// show profile for query query_id;
show profile for query 16;
// 查看指定query_id的sql语句cpu的基本使用情况
// show profile cpu for query query_id;
// 第四种方法
// explain执行计划
// 获取执行select语句的信息,包括在select语句执行过程中如何连接和连接的顺序
// explain + 完整select语句;
// exlanin字段分析
// type表示连接类型,由好到差分别为
// NULL表示没有经过表查,例如直接select 1+1;
// system一般只有访问系统表时才会有这个速度
// const表示直接访问主键的速度
// eq_ref表示访问唯一索引扫描的速度
// ref表示通过非唯一索引访问的速度
// range通常出现在 in(), between ,> ,<, >= 等操作中。使用一个索引来检索给定范围的行
// index指的是遍历索引
// all表示全表扫描
// NULL, system, const, eq_ref, ref, range, index, all;
// --------------------------------------------------------------------------------------------------
// 索引使用注意事项
// 最左前缀法则
// 如果索引了多列,如果跳过某一列,后面的字段索引失效
// 只要索引存在就行,跟放的前后位置无关
// 使用>或者<,后面的索引将会失效,而>=与<=不受该限制
// 不要在索引列上进行运算,否则索引失效
// 字符串类型不加''直接进行查询,可以查到对应结果,但是索引会失效
// 模糊匹配中,如果字段前面使用模糊匹配,索引会失效,字段后面使用则不会失效,如'软件%'与'%工程'
// 用or分开的条件,只有当or前与or后的条件都有索引时,涉及到的索引才会生效
// mysql会自动评估使用索引与使用全表扫描的查询速度,会选择速度更快的那种
// sql提示
// 当一个字段有多个索引可以使用时,可以选择不用或者用某个索引
// use指的是给mysql建议用某个索引,ignore指的是忽略某个索引,force指的是强制mysql使用某个索引
// select * from table_name use index(index_name) where 条件列表;
// select * from table_name ignore index(index_name) where 条件列表;
// select * from table_name force index(index_name) where 条件列表;
// 当查询到没有索引的字段时,就会出现回表查询,因为辅助索引的节点中没有相应的字段,所以需要根据查找到的id回到聚集索引再次查找,所以回表查询的时间更加长
// 所以在sql查询中尽量避免使用select * ,除非创建了一个包含表中所有字段的聚集索引
// using index condition 表示该查找使用了回表查询
// using where;using index 表示使用了索引,但是需要的数据都在索引列中能找到,所以不需要回表查询数据
// 前缀索引
// 当所需要查询的字段中有非常长的字符串时,这样会让索引空间占用很大,并且影响查询效率
// 因此,我们建立索引时可以只提取部分前缀字符串建立索引
// 其中n表示提取字符串的前n个字符建立索引
// create index index_name on table_name(column(n));
// 在业务场景中,如果存在多个查询条件,考虑针对于查询字段建立联合索引
// 尽量选择区分度高的建立索引,尽量建立唯一索引
// 要控制索引的数量,索引不是多多益善
// 如果索引列不能包含NULL值,在创建表时使用NOT NULL进行约束