-----------------------------------------------------------------------------------------------------------------
优化概述:
存储层:存储引擎,列类型,范式规范
设计层(单台服务器):索引,缓存,分区(分表)
架构层:读写分离(主从复制)
SQL语句层:更合适的SQL语句
(1)什么是存储引擎?
Mysql中的数据通过各种不同的技术(格式)存储在文件(或者内存)中的.技术和本身的特性就称为"存储引擎".
不同的存储引擎,获得不同的速度或者功能
*查看数据库中表的存储引擎.
show table status from 库名;
*查询存储引擎:
show engines;
(2) 存储引擎的分类:
如下图:
Mysql中主要的两种存储引擎: MyISAM 和 InnoDB
MyISAM和InnoDB的对比:
如下图
事务:将多条SQL语句看成一个整体,成功则全部成功,失败就全部失败;
回滚机制:当事务中的某条sql执行失败,则数据会回滚至未执行sql的状态
如何选择mysql数据库的存储引擎呢?(即对MyISAM和InnoDB的选择)
1) 要求执行sql执行速度快,并且数据完整性要求不是很严格的情况下,选MyISAM.例如:cms(内容管理系统),论坛,贴吧,微博.
2) 数据完整性要求非常严格的,必须使用InnoDB引擎,例如:银行系统,网上商城
3) 具体的情况可以根据存储引擎的不同来具体选择.
其他的引擎的介绍:
Memory:数据至于内存的存储引擎,拥有极高的插入,更新和查询的效率.但是会占用和数据量成正比的内存空间,并且内容会在重启之后消失.
Archive:
归档存储引擎,只支持数据的查询和写入,经常用于存储写日志信息.
1.为什么要进行列类型的优化?
1) 不同类型的数据,占用的存储空间不同,会影响表文件的大小
2) 不同类型的底层机制不同,sql对其的查询的速度也不同,选择合适的类型可以加快sql的执行效率.
2. 具体类型的优化
1) 整型的优化:
优化原则:尽可能小地占空间,使用unsigned在很多情况下能够增加数据存储
例题:
1) 人的年龄(unsigned tinyint)、狗的年(tinyint)、乌龟的年龄(smallint unsigned)
2) 京东商城的商品类别id(samllint unsigned)
3) 华为erp系统的用户id(mediumint)
4) 优酷会员id (int)
5) 优酷视频的id(int)
2) 字符串类型优化
Varchar(0-65535): 可变字长。
例如:Varchar(10) 存放:abc 实际占用3个字节。 节约存储空间,查询效率低
Char(0-255): 固定字长。
例如:Char(10) 存放:abc 实际占用10个字符。查询效率高
例题:
手机号: char(11)
座机号: 3位区号-8位号码 4位区号-8位号码 4位区号-7位号码 char(12)
用户密码: md5 char(32)
用户名: varchar(20)
文章标题: varchar(20 文章摘要: varchar(100)
3) 时间类型
unix_timestamp() 将字符串日期转换为unix时间戳
from_unixtime() 将unix时间戳转换为字符串日期
建议:
如果系统中存在大量的时间运算,使用unsigned int方式;
反之,可以选择使用 mysql内置的date datetime timestamp等类型.
4) Ip类型数据的存储
使用整型,不要使用字符串类型
ip地址通过整型保存
mysql: inet_aton(ip) inet_ntoa(数字)
php: ip2long(ip) long2ip(数字)
注意!
1. 不要使用允许空,除非有特殊要求时,否则一定要加not null属性,因为设为允许空占用的空间比非空的占用更大.在执行SQL时允许空的执行也更复杂.
2. 不要使用* 要使用具体的字段名称
总结列类型的优化:
1) 整型数据,尽量使用占用空间小的。能用tinyint不用samllint,能用samllint不用mediumint,....
2) 能使用整型,不用字符串。 ip地址转整型
3) 能使用枚举和集合,不用字符串。
4) 使用字符串时,合理选择char和varchar。固定长度选择char,可变长度使用varchar,但是要根据实际情况将长度设置的尽量短。
5) 时间格式根据情况选择使用int还是时间类型。经常参与运算,建议使用int;反之,使用date datetime等。
(三)数据库的设计范式:
第一范式:确保每列的原子性
第二范式:确保表中的每一个列都和主键相关
第三范式:确保每列都和主键直接相关,而不是间接相关
逆范式:在实际项目中根据用户的使用习惯.结合表查询的速度,来综合评估可以是否违反某个范式
=====================================================================
索引是把字段A的内容储存在一个独立区间S里,里面只有这个字段的内容和其对应的物理地址。在找查与这个字段A相关的内容时会直接从这个独立区间里查找,而不是去到数据表里查找。该查找速度非常快,因为索引内部有排序算法。
找到的符合条件的字段后再读取字段A所指向真实的数据记录的物理地址,再把对应的数据内容输出。
如果你查找的不是索引的字段那么他会从数据表里面查找。数据表有很多不相关的字段,数据库程序是不会省略查找的。要判断那些不相关的字段以及多次在记录中跳转是要花费一定的资源的。
索引就像一本书的目录,例如:你想看一本书的第20章,你会先查看目录中第20章所处的页数,然即时翻到第20章所处的页数,而不用一页一页翻过去,索引相当于目录功能,助你快速查询
(1) 主键类型 关键字不重复 不能为null;
(2) 唯一索引 关键字不重复
(3) 普通
(4) 全文
MyISAM支持,针对char,varchar,text起作用
复合索引
一个索引可以对应多个字段
(5) 创建索引:
------------------------------------------------------------------------------------------------
创建表同时设置索引:
create table 表名(
字段~~~~~~~~~
primary key (id),
unique index 名字(字段),
index 名字(字段),
index 名字(字段,字段), --复合索引
fulltext index 名字(字段);
)
------------------------------------------------------------------------------------------------
修改表并设置索引:
alter table 表名
add primary key (id),
add unique index 名字(字段),
add index 名字(字段),
add index 名字(字段,字段), --复合索引
add fulltext index 名字(字段);
------------------------------------------------------------------------------------------------
删除
修改表并设置索引:
alter table 表名 drop primary key;
alter table 表名 drop index 名字, --唯一、普通、全文
------------------------------------------------------------------------------------------------
(6)适合索引的场景
① 通过where设置条件语句
② order by 设置
③ 索引覆盖
④ 连接查询,外键索引
(7)使用索引原则
① 列独立
② 左原则
③ 复合索引
④ OR原则
如何创建索引
分析每个数据表可能执行的全部sql语句,把经常用到的条件字段加以统计并设计为索引。
利用explain获得sql语句的执行时间
一般如下相关的sql语句都需要设计为索引:
① 执行频率高
② 执行时间长
③ 业务逻辑重要
(8)前缀索引(好处:索引体积小、运行速度快)
alter table 表名 add index (字段(N))
计算前缀索引,具体使用多少位的前缀
总记录数量/不重复的信息数量 = 比值
比值=1 即可用于前缀索引设置
(9)全文索引的特点
①MyISAM支持,MySQL5.6以上版本支持InnoDB的全文索引
②全文索引目前只支持英文,不支持中文
③分词技术:将一个搜索关键词拆分为若干个单词,并且匹配每个关键词
④主要作用于 varchar,char,text类型字段
⑤MySQL内置的全文检索有自己的一套分词算法,其会自动忽略语气词,常见词,出现在50%的关键词。
(10)全文索引 match() against()
具体使用:
select * from 表名 字段 like '%条件内容%';
需要变形为如下才会使用全文索引:
select * from 表名 where match(字段) against (条件内容 in boolean mode)
(三) 索引的结构(看不懂)
Myisam非聚集索引
B+Tree索引结构
Innodb聚集索引
B+Tree索引结构