1. 数据库性能瓶颈

1.1. 高并发读写需求
1.2. 海量数据
1.3. 高可用高拓展

2. 影响数据库性能因素

2.1. 1.需求是否合理
2.2. 2.硬件(网络 带宽)
2.3. 3.sql编写
2.4. 4.表的设计

3. 发现问题

3.1. 定位慢查询

3.1.1. 熟悉数据库的状态相关命令
运行时间
show status like ‘uptime’;
如何设置慢查询时间
show variables like ‘long_query_time’ ; //可以显示当前慢查询时间 , 默认阈值 10s
set long_query_time=1 ; //可以修改慢查询时间 , 可以通过my.ini永久修改
如何开启慢查询
开启全局日志慢查询日志SET GLOBAL slow_query_log = 1 //开启慢查询日志
如何查看数据库sql的运行过程
show processlist
3.1.2. 步骤总结
1)关闭原有mysql服务2)以支持记录慢sql的方式来启动mysql
3)设置慢查询时间阀值4)构造慢sql
5)到日志文件中找慢sql(data.dir)

3.2. sql死锁

3.2.1. MySQL有两种死锁处理方式:
等待,直到超时(innodb_lock_wait_timeout=50s)。
发起死锁检测,主动回滚一条事务,让其他事务继续执行(innodb_deadlock_detect=on)。
由于性能原因,一般都是使用死锁检测来进行处理死锁
3.2.2. 检测到死锁之后,选择插入更新或者删除的行数最少的事务回滚,基于 INFORMATION_SCHEMA.INNODB_TRX 表中的 trx_weight 字段来判断。

4. 分析问题

4.1. explain关键字 慢sql语句

4.1.1. type
显示联结类型,显示查询使用了何种类型,按照从最佳到最坏类型排序1、system:表中仅有一行(=系统表)这是const联结类型的一个特例。2、const:表示通过索引一次就找到,const用于比较primary key或者unique索引
4.1.2. possible keys 可能用到的索引
4.1.3. key 实际使用的索引
4.1.4. rows 扫描的行数

5. 单机优化

5.1. 1.表设计 (3nf与反3nf)

5.1.1. 3nf

1NF: 即表的列的具有原子性,不可再分解,即列的信息,不能分解.只要数据库是关系型数据库,就自动的满足1NF.关系型数据库中是不允许分割列的即:列唯一
2NF :表中的记录是唯一的.通常我们设计一个主键来实现,即:行唯一
3NF: 即表中不要有冗余数据,就是说,表的信息如果能够被推导出来,就不应该单独的设计一个字段来存放。可以理解为:A表不能出现B表中非主键字段

5.1.2. 反3nf如何数据更新

1.额外发一条sql
2.触发器
反3NF :3NF指的是A表不能出现B表中非主键字段,如果出现了,那这个字段就是冗余字段,违反了三范式

5.2. 2.选择合适的存储引擎

5.2.1. myisam与innodb区别

事务安全:myISAM不支持事务,INNODB支持查询和添加速度:MyISAM速度快,INNODB速度慢支持全文索引:MyIsam支持,innodb不支持锁机制 MyIsam表锁 innodb行锁外键 MyISAM 不支持外键约束, INNODB支持外键. (通常不设置外键,通常是在程序中保证数据的一致)
5.2.2. MyISAM存储引擎:如果表对事务要求不高,同时是以查询和添加为主的,我们考虑使用myisam存储引擎. 比如 bbs 中的 发帖表,回复表.
INNODB存储引擎: 对事务要求高,保存的数据都是重要数据,我们建议使用INNODB,比如订单表,账号表.
Memory 存储:比如我们数据变化频繁,不需要入库,同时又频繁的查询和修改,我们考虑使用memory, 速度极快

5.3. 3.索引

5.3.1. 分类

普通索引Normal

允许重复的值出现,可以在任何字段上面添加

唯一索引

列中的值不能重复 但是允许存在null,并且可以有多个null(用户名、手机号码、身份证、email,QQ)

主键索引

指定了主键以后会自动创建。唯一且没有null值

全文索引

用来对表中的文本域(char,varchar,text)进行索引, 全文索引针对MyISAM有用InnoDB不支持全文索引,所以一般不用,默认只支持英文. -使用ES,Lucene代替就ok

5.3.2. 定义

帮助数据库快速定位查询数据,其底层使用特殊的数据结构重新组织数据,然后使用特殊的查询方式提高效率。 以空间换时间 会牺牲插入 删除 修改的效率

5.3.3. myisam索引

索引和数据是分开存储的
索引查询的时候的流程
叶子节点存储的都是数据地址

5.3.4. innodb索引

索引和数据都存放在ibdata1中 使用的是b+树
MySQL如果使用InnoDB存储引擎,数据库文件类型就包括.frm、ibdata1
主键索引和辅助索引
如果是主键索引 叶子节点存储的是完成的数据 如果是辅助索引 存储的是主键的key
什么是回表 什么是覆盖索引
辅助索引扫描完之后还会扫描主键索引
如果Select name 查询的列正好包含在辅助索引的节点的键值中,它就不需要在扫描主键索引了,这个叫覆盖索引。所以不要写Select *

5.3.5. 为什么要使用b+树作为底层的数据结构

b+树非叶子节点都不会存储数据 因此查询效率相对稳定
b+每个节点的大小是16kb,全部存储key和地址可以存储更多,可以是树的深度变矮 减少io次数
b+树叶子节点形成一个有序的链表 支持范围和排序

5.3.6. 索引的创建

单列和多列索引

普通索引(单列索引):该索引只在一个列上面创建
复合索引(多列索引):该索引只在多个列上面创建
多列索引具有向左匹配得原则 必须使用到第一部分才会使用索引

索引创建的原则

where或者order by后的字段
更新不频繁的字段
重复度不高

5.4. sql优化

5.4.1. dql的优化

1.小表驱动大表
2.平时写sql的时候注意索引失效的写法、
or
like前置匹配
运算
is null判断 in 不等于 。。。。。。
3.分页偏移量过大的时候
利用带有索引的字段先确定偏移位置 再取后面几位

6. 多机优化

6.1. 主从同步

6.1.1. 主库会将更新数据存入一个binlog二进制文件,从库使用一个授权的账号读取二进制文件,写入一个中继日志中,将中继日志还原成sql执行,即可完成主从的数据同步。

6.2. 读写分离

6.3. 分表分库