首页 > 代码库 > 一.mysql优化

一.mysql优化

一.mysql优化

1.网站请求走向分析优化的方面

 

需要优化的地方:

a:网络优化,服务器硬件方面,CDN加速(访问离用户最近一台服务器获取资源文件(jquery,js))

b:页面静态化处理,访问速度更快

c:php代码本身需要优化(需要自身经验的积累)

d:使用memcache,redis减轻数据库的压力,减少磁盘的i/o开销

e:mysql本身的优化

f:mysql架构(读写分离,主从复制)

2.mysql的优化的方向

存储层:选择合适的存储引擎,选择适当的列类型

设计层:给数据表建立合适的索引,满足表的三范式(逆范式)

sql层:优化更快的sql语句

mysql架构层:mysql读写分离

二.数据表的引擎

1.介绍

不同的数据库引擎有不同的数据结构,也有不同的功能,如:innodb引擎支持事务(ACID)的操作

ACID解释:

原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)

2

2.数据表引擎

2-1.查看数据表支持引擎种类

 

2-2.数据表引擎的区别

这里重点说myisam引擎和innodb引擎的区别(企业基本使用者两种引擎)

 

 

总结innodb和myisam引擎的区别:

①innodb引擎支持事务(ACID特性),myisam不支持

②myisam支持表锁(对某一行进行编辑.会锁住整个表,不适合并发高的网站)

  innodb引擎支持行锁(对某一行操作,不会阻塞其他行的操作)

③myisam引擎支持全文索引(只对英文有效),innodb引擎不支持

后面使用sphinx(斯芬克斯)中文搜索引擎技术

④innodb支持外键,myisam不支持(很少使用,一般建立一个额外的字段和其他表关联)

2-3.myisam和innodb引擎在生产环境的适用场景

①适合于网站主要是读写的,业务不高的网站.如:bbs,blog网站

②要求一致性较高的网站(依据事务特性),用innodb引擎

③并发量高的网站建议使用innodb引擎(主要是锁机制影响)

 

企业常见mysql引擎的面试:

1.mysql有哪些引擎,区别在哪里?

:见上文

2.如何选择合适的存储引擎

:一般使用innodb引擎,因为它支持事务操作,对业务处理场景要求较高,使用于并发量高的网站.一句话:使用innodb引擎

2-4.myisam引擎和innodb引擎插入数据的对比

第一步:建立两个表,一个myisam,一个innodb引擎

 

第二步:给表插入相同的数据(不按照主键顺序插入)

 

第三步:查询各个引擎的数据

 

 

问题:如果需要大批量的数据插入,用什么引擎?

:用myisam引擎,因为插入数据的时候,不需要按照主键顺序排列,性能更高.(相对而言)

2-5.myisam引擎和innodb引擎生成数据表的方式

 

结论:

建立一个myisam引擎表的时候,会生成三个文件:

表名.frm:表的结构文件

表名.MYD:表的数据文件

表名.MYI:表的索引文件

 

建立一个innodb引擎表的时候,会生成一个文件:

表名.frm:表的结构文件

其数据文件和索引文件存放在mysql安装目录/data/目录下面的ibdata文件中.

 

2-6.引擎的数据结构(B-tree,了解即可)

 

特别注意:

主键就是一种索引(主键),索引就是一种数据结构

 

①myisam引擎(非聚合结构)

 

 

 

②innodb引擎(聚合结构)(聚簇结构)

 

 

结轮:问题,如果需要大批量的查询数据库,使用innodb,因为不需要做回行操作(相对myisam而言)

 

注意:因为不管是innodb还是mysiam引擎,其本质都是要操作我们的磁盘,都是需要磁盘i/o开销(mysql最大的瓶颈就是在磁盘i/o方面),

所以如果某个数据频繁访问,我们可以先把数据缓存在memcache中去,下次直接请求memcache中的数据,可以减轻mysql数据库的压力.

2-7.数据的备份

①数据库备份和还原的指令

 

 

 

②备份操作

 a:先创建一个数据库,并且在建立一个数据表

 

mysqldump -u用户名 -p密码 数据库名>备份的路径(后缀名为sql)

 

备份的文件的如下:

 

③还原

删除之前的数据库,在建立一个数据库:

 

 

mysql -u用户名 -p密码 数据库名<备份的路径(后缀名为sql)

 

 

 

 

 

也可以通过mysql终端的source指令进行还原:

 

也可以通过mysql可视化工具来完成:

 

 

三.数据列类型的优化

1.选择列类型的原则

 

  decimal(8,2):存储跟钱有关的数据,8表示长度,2小数点后面保留两位

      能用char的尽量用char,固定长度的列处理数据的速度更快.

 

 mysql帮助指令, help 命令:

 

 

 

学习一个技能的时候,需要掌握获取这个知识的过程

 

 

2.存储数据的范例

存储性别:tinyint,女-1, 男-0, 保密-2

存储标题:空间不确定使用varchar,如果确定数据长度范围10-20,建议使用char(20)

存储时间:int或date

建议使用int类型来存储时间,原因可以方便根据时间戳查询,方便处理,处理更加灵活.

存储文章:用text

存储ip:用整数int(整数数据类型处理速度要快于字符串数据类型)

$_SERVER[‘REMOTE_ADDR’]=’192.168.148.188’

 

mysql中ip地址和整数互相转化的方法:

 

 

 

php中ip地址和整数互相转化的方法:

 

 

 

四.数据表的三范式

1.第一范式(1NF)

就是要保证每个字段的原子性,不可以在进行分割

有个用户表:

id name age address

1 小妹 18 广东省广州市白云区**街道12

1 小美 20 广东省深圳保安区**街道15

 

以上的address字段可以再进行分割,没有满足第一范式,我们可以对其分割多个字段来存储

id name age province city area

1 小妹 18 广东省 广州市 白云区**街道12

1 小美 20 广东省 深圳保 安区**街道15

2.第二范式(2NF)

在满足第一范式的前提下,要保证每条记录的唯一性,解决办法,给表设置一个主键字段即可

id name age province city area

1 小妹 18 广东省 广州市 白云区**街道12

2 小美 20 广东省 深圳保 安区**街道15

3.第三范式(3NF)

在满足第二范式的前提下,保证每条记录只存储一种类型的数据,为了解决数据的冗余

学生表为例:

id name age classid classname teacher

1 小妹 18   2 工程系 李老师

2 小美 20   3 美术系 许老师

3 小洪 22   2 工程系 李老师

4 小虎 21   2 工程系 李老师

 

可以将以上的表设计为两张表来存储,一张学生表,一张系表

学生表:

id name age classid

1 小妹 18   2

2 小美 20   3

3 小洪 22   2

4 小虎 21   2

 

系表:

id classname teacher

2 工程系 李老师

3 美术系 许老师

 

4.逆范式

我们一般建表基本都是满足三范式,但是有时候为了方便业务逻辑的处理,为了更好维护,我们可以适当的违反三范式,我们把这种设计称之”逆范式”.

 

 

五.索引

1.索引的介绍

生活上面:公交站牌,书本的目录

 

索引就是一种数据结构,在文件中已经是按指针排好序了,主要提高我们的查询数据的速度.

 

注意的地方:

一个表中的索引不是越多越好,适当即可,索引越多对我们的更新,删除效率会有所降低,

一个网站百分之70%-80%都是select操作,其他的都是我们的修改操作

 

2.索引的分类

①主键索引:一个表只能有一个主键索引,但是可以有复合主键索引.

②普通索引:一个表可以有多个普通索引.

③唯一索引:一个表可以有多个唯一索引,就是字段的值不可以相同

提示:一般使用程序控制一个字段的唯一性;

④全文索引:只有myisam引擎才有(mysql5.6版本后也有),只对英文有效,对中文索引采用sphinx来操作

⑤复合(多列,联合)索引:由多个字段组成的索引.

3.索引的操作

3-1.索引的创建

创建索引一般都是在建表语句中建立好,或者是通过alter修改语句添加索引,还有可以通过create语句也可以添加索引

 

a:建表的时候创建索引

#建表创建索引

create table t_key(

    id int not null auto_increment,

    title varchar(30) not null default ‘‘,

    email varchar(30) not null default ‘‘,

    addtime date ,

    primary key(id),

    key title_key(title),

    unique key email_uni_key(email)

);

 

b:通过alert语句建立索引

 

 

3-2.删除索引

alter table tablename drop primary key:删除主键

alter table tablename drop key  key_name:删除普通索引,唯一索引

 

查看建表语句:

 

删除操作:

 

4.使用蠕虫复制大数据表,进行有无所索引测试对比

 

 

 

 

 

 

至于为什么使用索引查询这么快,怎么知道?

可以在select前面加一个explain select ....

获取加一个desc select ............

 

5.explain执行计划

5-1.介绍

 

5-2.explain具体操作

 

针对有问题的sql语句进行优化,把no_index建立一个普通索引:

 

建立索引之后再次查询测试结果:

 

 

6.使用索引的原则

①经常出现在where条件后面作为查询条件的字段

②不要对索引字段使用运算或函数处理

 

③ like原则

like “aaa%” :可以使用到索引

like “%aaa%” :可以使用到索引

 

进行测试:

第一步:给title字段建立普通索引:

 

第二步:进行like模糊查询测试

 

 

④对于or查询,or前后的字段都必须是索引,如果其中一个不是,那么都将使用不到索引查询

 

⑤复合索引的最左原则

只要使用到复合索引的最左边的字段,那么后面的字段才会使用到

 

key(a,b,c) :给a,b,c三个字段设置复合索引

 

可以使用到索引的组合:

where a=’’

where a=’’ and b=’’

where a=’’ and b=’’ and c=”

 

 

 

查询测试:

 

六.针对sql语句的优化

①优化order by 语句

 

一句话,尽可能的使用到主键索引进行查询

 

②针对limit语句优化

select * from t_big  limit 100000,10 :

 

 

limit 1400000,20  ---->3.11s

limit 1490000,20  ---->3.30s

limit的起始位置越大,那么耗费查询时间越长,

 

解决办法:使用覆盖索引+延时关联技巧

 

覆盖索引:当查询到的字段恰好是索引的字段

 

覆盖索引+延时关联技巧:

select * from t_big  limit 1490000,20  ---->3.30s

select  t1.* from t_big as t1  inner join (select id as idd  from t_big  limit 1490000,20) as t2

where t2.idd=t1.id;

select  t1.* from t_big as t1  inner join (select id as idd  from t_big  limit 1590000,20) as t2

where t2.idd=t1.id;

 

结论:时间比之前耗费了更短时间.

 

 

 

七.慢查询日志

1.介绍

我们程序员可以定义一个时间界限(3s),只要有sql语句的执行时间超过我们所规定的时间界限,

就会被记录在日志文件里面,我们就可以在日志文件中找出这些有问题(所规定的时间界限)的sql语句,从而优化它.

2.开启慢日志查询

第一步:开启慢查询;

 

第二步:去mysql配置文件my.ini添加以下两行:

重启mysql服务器:

 

 

第三步:进行sql语句测试:

 

提示:在以后的开发建立大家开启慢日志查询,定义一个时间界限,时隔一段时间就去查看慢日志文件,看有没有比较慢的sql语句,从而优化它.

 

八.profile工具

1.介绍

使用profile工具,可以知道一条sql语句所花费的时间的具体情况,花费在哪些地方.

2.具体操作

第一步:开启profiling

 

 

第二步:进行sql语句测试

 

第三步:使用show profiles:查看所有开启profiling工具后的所有的sql语句

 

第四步:查看某一条sql语句所花费的时间

 

 

 

 

 

一.mysql优化