mysql优化
什么是三范式
表的范式,是首先符合1NF,才能满足2NF,进一步满足3NF。
1NF:表的列具有原子性,不可再分解,即列的信息不能分割。只要是关系型数据库就满足1NF。
2NF:表中的记录是唯一的,就满足2NF,通常用一个主键来实现。主键一般是不包含业务逻辑的自增。
3NF:表中不要由冗余数据,即表中的数据能被推导出来,就不应该单独设计这个字段。(在一对多的情况下,为了提高效率,可能在1这张表中,提高效率)
优化主要包括以下几种方式:
表的设计合理化(符合3NF)
添加适当索引(可以分为主键索引、普通索引、唯一索引、符合索引、全文索引)
分表技术(水平、垂直分表)
读(select)写(update、delete、add)分离
存储过程(模块化编程,可以提高编程)
对mysql的配置优化
- 配置最大并发数
- 调整缓存大小
7.mysql服务器硬件升级
8.定时清除不需要的数据,定时进行碎片整理
mysql是一个dbms即关系数据管理系统,sql语句写好之后,由数据库对我们进行编译并执行。而存储过程是事先编译好了。
sql语句本身的优化
从项目中迅速定位执行速度慢的语句(定位慢查询)。
- show [session|global(session会话级别,默认session)]status
可以显示数据库的状态:
show status like 'uptime' ;
显示运行时间show status like 'com_select'(select、update、add、delete);
当前执行的多少次查询show status like 'connections';
显示连接数- `show status like 'slow_queries';``显示慢查询次数(mysql默认10s以上是慢查询)
show variables like 'long_query_time';
可以显示当前慢查询时间。set long_query_time = 1;
修改慢查询的时间为1秒。
默认情况下,mysql不会记录慢查询,需要在启动mysql的时候,指定记录慢查询。
在log文件中,可以查看满查询的信息。
建立适当的索引,是最方便的提高效率的方式。
添加索引
主键索引
主键索引不能为空,也不能重复
当把一张表,某个列设为主键的时候,则该列就是主键索引
创建主键索引:
alter table 表名 add primary key [索引名] 列名
普通索引
一般是先有表,再创建普通索引
create index 索引名 on 表名 (列1,列2)
全文索引
FULLTEXT索引仅可用于myisam数据库
全文索引的使用方法:
select * from 表名 where match(列a,列b...) against('关键字')
针对英文生效,需要使用sphinx(coreseek)技术处理中文
停用词:一些常用词和字符就不会创建索引
唯一索引
当表的某列被指定为unique约束是,这个列就是一个唯一索引
唯一索引可以为空,且能多个空。
create unique 索引名 on 表名 (字段列表)
查询索引
desc 表名; 缺点:不能显示索引名称
show index from 表名
show keys from 表名
删除索引
alter table 表名 drop index 索引名;
删除主键索引还有其他方法:
alter table 表名 drop primary key;(因为一个表只有一个主键索引,不用去指定索引名)
修改索引
先删除再创建
使用索引的注意事项:
- 占用磁盘空间
- 对dml操作有影响,会变慢。(增删改的时候,索引会改变,需要重整索引)
- 适合所有的情况
- 较频繁额作为查询条件字段应该创建索引
- 内容单一的字段不该创建索引(比如都是1、0的等)
- 更新很频繁的字段不适合创建索引
- 不会出现在where子句中字段不该创建索引
索引的使用:
- 如果索引中有复合索引,使用了最左边的列,就会启用这个索引。
- 在使用模糊查询的时候,如果左边有‘%’,则索引失效。
- 如果条件中有 or,要求所有字段都必须建立索引。建议少使用or关键字。
- 如果列类型是字符串,则一定要在条件中将数据使用引号引起来。
- 如果全表扫描比使用索引快,则不适用索引。
查看索引的使用情况:
show status like 'Handler_read%';
返回实例:
Handler_read_first 10
Handler_read_key 1327
Handler_read_last 0
Handler_read_next 288
Handler_read_prev 0
Handler_read_rnd 13063
Handler_read_rnd_next 69252
handler_readk_key:这个值越高越好;
handler_read_rnd_next:这个值越高,说明查询效率低
sql小技巧:
- 在使用
group by
分组查询时,默认分组后,还会排序,可能降低速度。在后面增加order by null
可以防止排序。 - 有的情况下,可以使用连接来替代子查询。因为join在mysql中不需要创建临时表。(使用左外连接更好)
mysql存储引擎的选择
myisam
存储:对事务要求不高,同时以查询和添加为主的。例如bbs中的发帖,回复表。innodb
存储:对事务要求比较高,保存的都是重要数据。如订单表,账号表。memory
存储:数据变化频繁,不需要入库,同时又频繁的查询和修改。
myisam
和innodb
的区别
- 事务安全:
innodb
事务安全 - 查询和添加:
myisam
查询添加快 - 全文索引:仅适合于
myisam
- 锁机制:
myisam
表锁,innodb
行锁 - 外键:
myisam
不支持外键 - 定时清理:
myisam
需要定时整理:optimize table 表名
