MySQL如何优化
表的设计合理化(符合3NF)
添加适当索引(index) [四种: 普通索引、主键索引、唯一索引unique、全文索引]
SQL语句优化
分表技术(水平分割、垂直分割)
读写[写: update/delete/add]分离
存储过程 [模块化编程,可以提高速度]
对mysql配置优化 [配置最大并发数my.ini, 调整缓存大小 ]
mysql服务器硬件升级
定时的去清除不需要的数据,定时进行碎片整理(MyISAM)

什么是数据库范式
为了建立冗余较小、结构合理的数据库,设计数据库时必须遵循一定的规则。在关系型数据库中这种规则就称为范式。范式是符合某一种设计要求的总结。要想设计一个结构合理的关系型数据库,必须满足一定的范式。
第一范式:是对属性的原子性约束,要求属性(列)具有原子性,不可再分解;(只要是关系型数据库都满足)
第二范式:是对记录的惟一性约束,表中的记录是唯一的, 就满足, 通常我们设计一个主键来实现,主键不能包含业务逻辑。
第三范式:是对字段冗余性的约束,它要求字段没有冗余。 没有冗余的数据库设计可以做到。
但是,没有冗余的数据库未必是最好的数据库,有时为了提高运行效率,就必须降低范式标准,适当保留冗余数据。具体做法是: 在概念数据模型设计时遵守第三范式,降低范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字段,允许冗余。
mysql优化主要是对慢查询进行优化。
什么是慢查询
MySQL默认10秒内没有响应SQL结果,则为慢查询
可以去修改MySQL慢查询默认时间
如何修改慢查询:
–查询慢查询时间
show variables like ‘long_query_time’;
–修改慢查询时间
set long_query_time=1; —但是重启mysql之后,long_query_time依然是my.ini中的值

如何定位慢查询
如何将慢查询定位到日志中
在默认情况下,我们的mysql不会记录慢查询,需要在启动mysql时候,指定记录慢查询才可以
C:\Program Files(X86)\MySQL\MySQL Server 5.7\bin
mysqld.exe --safe-mode --slow-query-log [mysql5.5 可以在my.ini指定](安全模式启动,数据库将操作写入日志,以备恢复)
cmd
mysqld.exe –log-slow-queries=d:/abc.log
my.ini 文件中有日志记录的位置
#Path to the database root
datadir=" C:\ProgramData\MySQL\MySQL Server 5.7\Data "
分表分库

垂直拆分
垂直拆分就是要把表按模块划分到不同数据库表中(当然原则还是不破坏第三范式),这种拆分在大型网站的演变过程中是很常见的。当一个网站还在很小的时候,只有小量的人来开发和维护,各模块和表都在一起,当网站不断丰富和壮大的时候,也会变成多个子系统来支撑,这时就有按模块和功能把表划分出来的需求。其实,相对于垂直切分更进一步的是服务化改造,说得简单就是要把原来强耦合的系统拆分成多个弱耦合的服务,通过服务间的调用来满足业务需求看,因此表拆出来后要通过服务的形式暴露出去,而不是直接调用不同模块的表,淘宝在架构不断演变过程,最重要的一环就是服务化改造,把用户、交易、店铺、宝贝这些核心的概念抽取成独立的服务,也非常有利于进行局部的优化和治理,保障核心模块的稳定性
垂直拆分用于分布式场景。
水平拆分
上面谈到垂直切分只是把表按模块划分到不同数据库,但没有解决单表大数据量的问题,而水平切分就是要把一个表按照某种规则把数据划分到不同表或数据库里。例如像计费系统,通过按时间来划分表就比较合适,因为系统都是处理某一时间段的数据。而像SaaS应用,通过按用户维度来划分数据比较合适,因为用户与用户之间的隔离的,一般不存在处理多个用户数据的情况,简单的按user_id范围来水平切分
通俗理解:水平拆分行,行数据拆分到不同表中, 垂直拆分列,表数据拆分到不同表中
水平分割案例

思路:在大型电商系统中,每天的会员人数不断的增加。达到一定瓶颈后如何优化查询。
可能大家会想到索引,万一用户量达到上亿级别,如何进行优化呢?
使用水平分割拆分数据库表。
什么是索引
索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存。如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录。表里面的记录数量越多,这个操作的代价就越高。如果作为搜索条件的列上已经创建了索引,MySQL无需扫描任何记录即可迅速得到目标记录所在的位置。如果表有1000个记录,通过索引查找记录至少要比顺序扫描记录快100倍。
索引的分类

主键索引
主键是一种唯一性索引,但它必须指定为“PRIMARY KEY”。如果你曾经用过AUTO_INCREMENT类型的列,你可能已经熟悉主键之类的概念了。主键一般在创建表的时候指定,例如“CREATE TABLE tablename ( […], PRIMARY KEY (列的列表) ); ”。但是,我们也可以通过修改表的方式加入主键,例如“ALTER TABLE tablename ADD PRIMARY KEY (列的列表); ”。每个表只能有一个主键。
创建主键索引
主键是一种唯一性索引,但它必须指定为“PRIMARY KEY”。如果你曾经用过AUTO_INCREMENT类型的列,你可能已经熟悉主键之类的概念了。主键一般在创建表的时候指定,例如“CREATE TABLE tablename ( […], PRIMARY KEY (列的列表) ); ”。但是,我们也可以通过修改表的方式加入主键,例如“ALTER TABLE tablename ADD PRIMARY KEY (列的列表); ”。每个表只能有一个主键。
当一张表,把某个列设为主键的时候,则该列就是主键索引

create table `inprimirykey`
(id int unsigned primary key auto_increment ,
name varchar(32) not null default '');

这是id 列就是主键索引.

CREATE TABLE `noprimirykey` (
  `id` int(11) DEFAULT NULL,
  `username` varchar(255) DEFAULT NULL
);

如果你创建表时,没有指定主键索引,也可以在创建表后,在添加, 指令:
实例:

alter table noprimirykey add primary key (id);

删除主键索引

alter table noprimirykey drop primary key;

查询索引
desc 表名; 不能显示索引名称
show index from 表名
show keys from 表名

01-30 08:36