SQL优化之索引优化

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL优化之索引优化相关的知识,希望对你有一定的参考价值。

 

这篇文章为Qi总结,如果有不对的希望可以指出。

 

初级开发人员,一般是接触不到架构,大数据这样的优化方案,而初级开发人员所做的优化一般只有SQl优化。

 一·举一个小例子:

在网站中,一般会设计到登录注册,但是登录方式出现了很多种,例如:用户名登录,手机登录,邮箱登陆,微信,微博,QQ,……等等很多种登录方式。

这么多登录方式如果放入一张表中,在编写SQL语句中会出现很多问题:

如果放入一张表中登录方式的SQL语句应该是这样的:

select * from user where uname=‘zhangsan‘ and upass=‘123456‘ or email=‘[email protected]‘ and email_pass=‘123456‘……

在这里不建议用*查询所有,这里只供测试使用,一个高质量的开发人员,应该取自己所需要的字段,如果数据表结构某天有所修改,也不会影响其效率;

回到优化方案,这样的一张表的SQL语句如果是相对较大的网站的话会极大占用系统资源,

优化方案:可以将不同的登录方式拆分成不同的表,这样在查询是只需要判断其登录方式去查询对应的表,极大的增加了查询速度。

弊端:因为分出去很多张表,也影响了写入,删除,修改的效率。

这里Qi号总结一下,任何的优化方案都不是凭空优化,会降低一部分的效率,提高一部分的性能,如果划算的话,就是合理的优化方案

 

二,优化小手段

在优化之前,查询很重要,所有的优化方案都是根据实际要求去优化的。

1. 查询当前程序增删改查的次数

mysql可以记录当前网站所有的增,删,改,查的次数,可以根据这些去采取优化方案

代码如下:

show [global|session] status like ‘Com_select‘;

参数介绍:

  global ---  MySQL服务器启动以后的全局属性,建议大家在测试时使用global属性 

  session(默认) --- 当前会话窗口执行增删改查的次数

 

  like ‘Com_select‘ Com_select 查找查询语句的次数

  like ‘Com_select‘ Com_delete 查找删除语句的次数

  like ‘Com_select‘ Com_update 查找修改语句的次数

  like ‘Com_select‘ Com_insert 查找插入语句的次数

 

所要做的工作:

将这些次数定期存入MySQL库中,并区分时间段,在执行优化方案之前查询时间段的增删改查次数,并根据这些分析去优化;

 

可选语句

show global status like ‘connections‘;       查看mysql被连接多少次

show global status like ‘Uptime‘;            MySQL工作运行时间(真实的,不可人为修改)

 

2.日志

MySQL有三种日志:这些日志一般都是存在mysql/data目录下

  bin_log日志(mysql-bin.00001)   : 用于1. 数据恢复 2. 主从数据库之间同步数据

  error日志(PC-20170406LOQL.err) : 错误日志:记录了MySQL服务器启动、关闭和运行时出错等信息

  慢日志 :admin-PC-slow.log   如果SQL语句超过慢日志的界定时间,则会被存入慢日志信息

 

查看慢日志的界定时间:

mysql> show variables like ‘long_query_time‘;

 

修改慢日志的界定时间
set global long_query_time=0.0001;//只要超过0.0001的语句都会被写入慢日志

 

可以根据存入慢日志的SQL语句去定制优化方案;

 

以上是开始优化之前需要做的准备工作,然后开始制定优化方案

三 开始优化

 有关索引的概念呢,Qi号在上一篇文章提到过,大家可以去看一下

1. 索引 优化

 

优化工具:分析解释语句

代码如下:

explain/desc select * from t1 where name=‘user99999‘\G;//分析 解释语句

执行结果

*************************** 1. row ***************************
id: 1                      查找的条数
select_type: SIMPLE              简单的查询,没有左连接,右连接,子查询的话就是SIMPLE
table: t1                    操作的表名
type: ALL ->ref()-> const(常量)-> system     索引的级别
possible_keys: NULL               可能用到的索引
key: NULL                    实际用到的索引
key_len: NULL                  索引的长度
ref: NULL
rows: 991159                   执行这条语句总共扫描的行数。(根据影响函数去优化)
Extra: Using where
1 row in set (0.00 sec)

 

在建立索引时,很少以一个条件建立索引

案例:分析用户的搜索行为 找出用户最常用的搜索方式 建立联合索引
select * from goods where cate_id=1 and price = 100 发现用户大多都是先搜类别在搜价格
给cate_id和price 建立联合索引
alter table good add index c_p (cate_id,price)

select * from good where cate_id=1 and price=2 and sell=100;发现用户大多先搜类别在搜价格在搜销量
给 cate_id price sell建立联合索引
alter table good add index c_p_s (cate_id,price,sell)

以上两种情况出现了索引冗余,但在真实的项目中 索引都是冗余的,为了提高每一种搜索的效率

注意:索引的左前綴原則 (越靠左的索引越能生效)
select * from good where cate_id=1 and price=2 and sell=100; 索引都能生效
select * from good where sell=100; 索引都不生效
select * from good where cate_id=1 and sell=100; cate_id索引生效


建立单个索引没实际意义 因为在实际项目中用户很少单一调价查询
alter table t1 add index c (cate_id);
alter table t1 add index p (price);

索引覆盖:innodb表中索引和数据绑定在一起,找到索引就找到数据 这样的行为叫做索引覆盖
聚蔟索引 (innodb) 非聚蔟索引 (myisam)

回行:myisam引擎的索引文件-》执行数据文件的过程叫回行

次级索引:除了主键的索引就是次级索引

myisam的次级索引指向 数据文件的地址
innodb的次级索引与数据不会捆绑在一起,innodb的次级索引指向主键索引的引用,然后在调用数据

 

好了,索引的优化方案就是这些,Qi号就与大家分享到这,有关SQl优化的文章其实有很多,博友们也可以去搜集。最后

 

今天也是照例与大家分享一道简单的面试题。

题目:

从0,1,2,3,4,5,6,7,8,9,这十个数字中任意选出三个不同的数字,“三个数字中不含0和5”的概率是             

知道答案的博友们可以在下方评论。

 

鸡汤:

今天分享的谚语是Qi号在北京西二旗某一家公司前看到的一块碑龙飞凤舞的写着:

空谈误国,实干兴邦

当时看到时也是有点小感触的,希望大家可以实际行动起来,在沮丧时可以抬头45度仰望天空,大吼一声:“php是最好的语言”,很爽的。

 



























以上是关于SQL优化之索引优化的主要内容,如果未能解决你的问题,请参考以下文章

优化SQL之最佳索引

Mysql知识汇总之常用索引及sql优化

MySQL之SQL优化详解

SQL性能优化策略之索引优化方法

SQL优化之语句优化

BATJ解决千万级别数据之MySQL 的 SQL 优化大总结