mysql索引及其优化

索引

1.基本sql语句

1.创建索引

CREATE  [UNIQUE | FULLTEXT | SPATIAL]  INDEX  索引名 ON  表名(字段名) [USING 索引方法]

2.删除索引

drop index 索引名

3.查看索引

show index on tablename;

2.性能下降的原因

1.查询语句写的烂
2.索引失效:单值索引, 复合索引
3.关联太多的join(设计缺陷或者不得一的需求)
4.服务器调优以及各个参数设置(缓存, 线程数)

3.优点

  1. 加快查询
  2. 减少排序

4.缺点

  1. 增加间隙锁,减慢更新数据的速度
  2. 花时间来建立优化的索引

5.分类

  1. 单值索引:只含单个列
  2. 唯一索引:索引中的值唯一,可以为空
  3. 复合索引:含有多个列的索引

6.检索原理

  1. B树
  2. hash
  3. r树
  4. 全文

7.什么情况下建立索引

  1. 主键自动建立索引(王者中的用户名和所在区不会是联合主键吧???不让经常更新,并且抽奖什么的使用用户名和分区就可以进行了!)
  2. 外键建立索引
  3. 用于分组统计、排序的字段建立索引
  4. 高并发倾向于建立联合索引
  5. 频繁查询的字段建立索引

8.什么情况下不建立索引?

  1. where中用不到的字段,比如用户自己的简介
  2. 频繁更新的字段不讲理索引
  3. 表的记录很少 3 million以下
  4. 数据中重复率太高

9.性能分析

1.explain

  1. 使用
  2. type
  3. extra
  4. row
  5. possilble key
  6. key
  7. table
  8. id
  9. ref

2. 慢查询日志

4.批量数据脚本

5.show profile

6.全局日志查询

7.总体思路

  1. 慢查询日志的开启并捕获。
  2. explain + sql的分析。
  3. show profile查询sql在服务器中的执行细节和声明周期。
  4. sql 数据服务器的参数调优。

10.性能优化

1. 单表连接

2.两表连接

1.左右连接加相反索引(左连接加右边表, 右连接加左边表)

3.三表优化案例

  1. 小表驱动大表
  2. 先优化子集
  3. 保证join的表已经有了优化语句
  4. 不要吝啬join buffer

4.索引优化原则

  1. 全值匹配我最爱
create index on user a('c', 'd', 'e');
select * from user where c = 'x';  #可以用到索引
select * from user where d = 'y' and  e = 'z' #索引失效了

第二个违背了最佳左前缀法则:
建立索引的第一字段不能丢(索引失效)
建立索引的中间字段不能断(否则部分使用索引)
  1. 不在索引上做任何函数操作(计算,函数,类型转化)
select * from user where left(id, 4) = 1;#在索引left上使用了函数

  1. 使用范围之后全失效,尽量选择(select)索引的字段
select * from user where id = 4 and age > 1 and name = "te";#使用了范围
范围之后的就失效了, id会用到索引,但是age和age之后就会出现索引失效
select id, age, name where id = 4 and age  > 1 and name = "te"#会使用索引,所以仍旧是使用索引
  1. 使用 <>, != ,is null, null ,is not null ,like "%name"等时候也会导致索引失效
select * from name where name like "%name";#索引失效
select * from name where name like "name%";#like 百分在右边

如果非得加载左边应该怎么样呢?
使用覆盖索引

create index on user idx_name_age(`name`, `age`);
select name, from user where name like "%tea%";
  1. varchar 类型一定加上单引号
select * from name = '3000';
select * from name = 3000;#索引失效
都能查到,但是出现了隐式的类型转换

带头大哥不能死, 中间兄弟不能断; like 后边百分号,字符串类型加引号,范围之后全失效。

  1. group by 有可能产生临时表
  2. 小表驱动大表。
select * from A where id in (select id from B);#B表小于大表
select * from A where exists(select id from B);#A表小于大表
exists就是把A中的字段放入子查询寻中进行比较。

猜你喜欢

转载自blog.csdn.net/fuzekun/article/details/104462447