一、什么是数据的优化
数据库的优化是一个综合型的技术,并不是通过某一种方式让数据库效率提高很多, 而使通过多方便的提高,从而使数据提高很多
主要包括
1. 表的设计合理化
2. SQL语句的优化
3. 给表要添加合适的索引 普通索引、主键所以,唯一索引 unique、全文索引
4. 分表技术(水平分割、垂直分割)
5. 定时清除垃圾数据、定时进行碎片整理
6. 多用存储过程,和触发器
7. 对mysql的配置进行优化[配置最大并发数my.ini,调整缓存大小]
8. 读写分离
9. myql服务器硬件是否要升级
表的设计合理化
三范式:
第一范式、
确保每列的原子性、所有的(不可再分)
注意:地址这个字段,如果不分类汇总,不排序,仅仅是起一个字符串的作用,这是我们不拆分(反三范式)
第二范式、
非键字段必须依赖与键字段(一个表做一件事情)
第三范式、
消除传递依赖(如果一个字段可以推到出到另外一个字段)
反三范式:
范式越高,数据的冗余就越少、但是有的时候效率就越底下,为了提高运行效率,可以适当
的适当的让数据的冗余。
数据库的性能比规范化更重要
SQL语句的优化
定位慢查询
增、删、改、查
一、MySql数据库一个关于状态的查询
show status指令 查询mysql的运行状态
show status like ‘com_insert’ 执行了多少次插入
show status like ‘com_update’ 执行了多少次更新
show status like ‘com_delete’ 执行了多少次删除
show status like ‘com_select’ 执行了多少次删除
show[session | global ] status like com_select’
show status like ''uptime' 显示MySql数据库启动多长时间,如果时间很长了,
数据库表的存储引擎是myisan的,这时候就要主要整理碎片。
二、显示慢查询
show variables like 'long_query_time'
set long_query_time = 0.5
show status like 'slow_queries'
定位慢查询(开启慢查询的日志)
一旦开启慢查询日志后,日志文件的位置,在my.ini文件去查找datadir
在默认情况下不会开启慢查询,如何开启慢查询呢
第一步: 关闭当前的MySql的服务
第二步: 启动 mysqld --safe -mode --slow-query-log
关闭 mysqladmin -uroot -p123456 shut down
优化问题
通过explain语句可以分析,mysql如何执行的sql语句
二、数据库的索引
一、建立适当的索引
高数据库性能,索引是最物美价廉的东西了,不用加内存,不用改变调用sql,只要执行正确的create index 查询速度就可能提高百倍千倍
二、添加索引
主键索引
当一张表中某个列设为主键的时候,则该列就是主键索引
create table aa(id int unsigned primary key auto_increment,
name varchar(32) )
这是id列是主键例
第一种 : 查询索引 desc 表名 不能显示索引的名字
第二种 : 查询索引的show index from 表名
第三种 : 查询索引的show keys from 表名、
如果你创建不表的时,没有指定主键索引,也可以在创建表后,在添加指令
alter table 表名 add primary key(列名);
emp.frm 表的结构
emp.MYD 表的数据
emp.MYI 表的索引
普通索引
普通索引的创建,是先创建表,然后添加索引
create index 索引的名字 on 表名(列)
唯一索引
当变的某列指定为unique约束时,这列就是一个唯一索引
create table ddd(
id int primary key not null,
name varchar(100) unique
)
全文索引
全文索引、主要是针对文件、文本的检索,全段索引对Myisam
错误的用法
select * from articles where body like '%mysql%'
正确的用法是
select * from articles where match(title,body) aginst('database')
说明
1.在mysql中fulltext索引指针对myisam生效
2.mysql自己提高的fulltest针对英文生效->sphinx(coreseek) 技术处理中文
3.使用方法是match(字段名) against(‘关键字’)
4.全文索引一个叫停止词
删除索引
alter table 表名 drop index 索引名
如果删除主键索引
alter table 表名 drop primary key
修改索引
先删除,在重新创建
为什么创建索引后速度会变快呢 BTree
三、 索引使用的注意事项
磁盘占用
对dml(update,delete,insert)语句的效率影响
频繁操作的适合建立索引,字段非频繁不适合建立索引,更新次数多的不适合建立索引
说明,如果我们的表中使用有复合索引(索引作用在多列上),此时我们
注意
1>对于创建得多列索引,只要查询条件使用了最左边的列,索引一段就会
被使用。
explain select * from dept where loc ="xxx"
2>对于使用like查询,查询如果是'%AA' 不会使用到索引‘aaa%’
会使用到索引
比如: explain select * from dept where dname like '%AAA'
不能使用 索引,既在like查询时,关键字,最前面,不能使用%或则)_这样
的字符,如果一定要前面有变化的值,则考虑使用全文检索->sphinx
3>如果条件中有or 即使用其中有条件带索引也不会使用,换言之,就是
要求使用所字段,都必须建立索引
id : 查询序列号
select_type:查询的类型
table:查询的表名
type:扫描的方式
possible_keys:这个表中可能使用了哪些索引
key 实际使用了哪些索引
key_len:
ref
rows:扫描了多少行数,可能得到多少记录
extra:sql语句额外信息,排序方式
索引的使用
查看索引的是使用情况
show status like 'Handler_read%';
大家可以注意
handler_read_key:这个值越高越好,越高表示使用索引查询到的次数
handler_read_rnd_next:这个值越高,说明查询低效
常用SQL优化
大批量插入数据(MySql管理员)
对于MyISAM
alter table table_name disable keys
loading dataa
alter table table_name enable keys;
对于Innodb
对于
1.将到导入的数据按照主键排序
2.set unique_checks= 0,关闭唯一性校验
3. set autocommit = 0,关闭自动提交
sql语句的小技巧
1> 在使用group by 分组查询,默认分组后,还会排序,可能会降低速度
2> 在group by 后面添加order by null 就不会排序
3> 在有些情况下,可以使用连接代替子查询,因为使用join MySql不需要在内存中
创建临临时表
select * from dept,emp where dept.deptno = emp.deptno
select * from dept left join emp on dept.deptno = emp.deptno
选择合适的存储引擎
myIsam 存储,如果表对事物要求不高,同时是以查询和添加为主的,我们考虑使用
myisan存储引擎
INNODB 存储,对事物要求高,保存的数据都是重要数据
memory: 存储,比如我们数据变法频繁,不需要入库,同时又频繁查询和修改,我们考试
使用memory
myisam innodb
批量插入的速度 高 低
事物安全 支持
全文索引 支持
锁机制 表锁 行锁
存储限制 没有 64TB
B数索引 没有 支持
哈希索引 支持
集群索引 支持
数据缓存 支持 支持
索引缓存 支持
数据可压缩 支持
空时使用 低 高
内存使用 低 高
支持外键
MyISaM 与 innodb
1.事物安全
2.查询和添加速度
3.支持全文索引
4.锁机制
5.外键MyISAM不支持外键
MyISaM删除数据文件变小
optimize table 表名
定时维护
三、数据库备份
一、手动数据库(表的)方法
cmd 控制台
mysqldump -uroot -proot 数据库[表名1 表名2] > 文件路径
比如 吧temp 数据库备份到d \temp bak
mysqldump -u root -proot temp>d:\temp.bak
二、如何使用备份文件恢复我的数据
在mysql环境
source d:\temp.bak
使用定时器来定时完成
一、在windows系统
mytask.bak 文件
mysqldump -u root -proot temp>d:\temp.bak
注意:
注意
1> 如果路径里面有空格需要加入双引号
2> mysqlump 写全路径
定时任务
windwxp
控制面板---> 任务计划
二、在linux系统
现在问题是,每次都是覆盖原来的备份文件,不利用我们分时间段进行备份,
crontab corn 表达式
理解事务的4种隔离级别 读
1.Read uncommitted (脏读)
读未提交
就是一个事务可以读取另一个未提交事务的数据。
2.Read committed (不可重复读) 读取两次数据不一致
读提交,顾名思义,就是一个事务要等另一个事务提交后才能读取数据。
如果对事物进行update操作时,读操作事物要等待这个更新操作事物提 交后才能读取数据,可以解决脏读问题
3.Repeatable read (幻读)读取两次数据一致
重复读,就是在开始读取数据(事务开启)时,不再允许修改操作
不可重复读对应的是修改,即UPDATE操作。但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作,而不是UPDATE操作。
4.Serializable 序列化
Serializable 是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。
一、什么数据库的事物
原子性、一致性、格力性、持久性
原子性(ATOMICITY)
一个事物必须视为一个不可分割的最小工作单元,整个事物中额所有操作
要么全部提交成功,要么全部失败,对于一个事物来说,不可能只执行其中
一部分操作。
一致性
一致性是指事物将数据库从一种一致性状态装换到另外一种一致性状态
,在事物开始之前和事物结束后数据库中数据的完整性没有破坏。
事物的隔离型(ISOLATION)
隔离性要求一个事物对数据库中数据的修改没再未提交完成前对于其他事物
是不可见的
事物的持久性
一旦事物提交,则其所做的修改就会永远保存到数据库中
什么是大事物
运行事物比较长,操作的数据比较多的事物
风险
锁定太多的数据、造成主从延迟大量的阻塞和锁超时回滚时所需时间比较长
回滚时所需时间比较上
执行时间长、容易造成主从延迟
1.避免一次处理大多的数据
2.移除不必要的查询操作
十、影响数据库性能
一、磁盘IO
风险
磁盘IO性能突然下降(使用更快的磁盘设备)
其他大量消耗磁盘性能的计划任务(调整计划任务,做好磁盘维护)
二、QPS和TPS
三、网卡流量
如何避免无法连接数据库的情况
1.减少从服务器的数据
2.进行分级缓存
3.避免使用select * 进行查询
4.分离业务网络和服务器网络
四、大表
一、可以称为大表
1.记录行数巨大,单表超过千万行
2.表的额数据文件巨大,表数据文件超过10G
二、大表查询的影响
慢查询:很难在一定的时间内过滤出所需要额数据
大表对DDL操作影响
风险
MySQL版本< 5.5 建立索引会锁表
MySQL版本 > = 5.5虽然不会锁表但会引起主从延迟
修改表结构需要长时间锁表
长时间的主从延迟
影响正常的数据操作
如何处理数据库中的大表
分库分表把一张大表分成多个小表
难点
分表主键的选择
分表后跨跨分区数据的查询和统计
大表的历史数据归档
减少对前端后端业务的影响
难点
1.归档的时间点的选择
2.如何进行归档操作
一、把一个实例中多个数据库查分到不同的实例
例如
MySQL节点一
订单 ---------用户---------------促销
订单节点node01
用户节点node02
促销节点node03
不能解决写负载----->
二、把一个库中表分离到不同的数据库中
订单节点node01 拆分到不同的节点中
订单表
商品表
购物表
三、数据库分片前的准备
如何选择分区键
1.要尽量避免跨分区查询的发生
2.分片键要尽可能使各个分片中的数据平均
如何无需分片的表
每个分片中存储一份相同的数据
使用额外的节点统一存储
如何在节点上部署分片
在每个分片使用单一数据库。并且数据库也相同
将多个分片存储在一个数据库中,并在表名上加入分片号后缀
在一个节点中部署多个数据库,每个数据库包含一个分片
数据库分片前的准备
如何分配分片中的数据
按分区键的Hash值取模来分配分片数据
按照区键的范围来分配分片数据
利用分区键和分片的映射表来分配分片数据