mysql优化

什么是三范式

表的范式,是首先符合1NF,才能满足2NF,进一步满足3NF。

1NF:表的列具有原子性,不可再分解,即列的信息不能分割。只要是关系型数据库就满足1NF。

2NF:表中的记录是唯一的,就满足2NF,通常用一个主键来实现。主键一般是不包含业务逻辑的自增。

3NF:表中不要由冗余数据,即表中的数据能被推导出来,就不应该单独设计这个字段。(在一对多的情况下,为了提高效率,可能在1这张表中,提高效率)

优化主要包括以下几种方式:

  1. 表的设计合理化(符合3NF)

  2. 添加适当索引(可以分为主键索引、普通索引、唯一索引、符合索引、全文索引)

  3. 分表技术(水平、垂直分表)

  4. 读(select)写(update、delete、add)分离

  5. 存储过程(模块化编程,可以提高编程)

  6. 对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文件中,可以查看满查询的信息。

建立适当的索引,是最方便的提高效率的方式。

  1. 添加索引

    主键索引

    主键索引不能为空,也不能重复

    当把一张表,某个列设为主键的时候,则该列就是主键索引

    创建主键索引: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 表名 (字段列表)

  2. 查询索引

    desc 表名; 缺点:不能显示索引名称

    show index from 表名

    show keys from 表名

  3. 删除索引

    alter table 表名 drop index 索引名;

    删除主键索引还有其他方法:

    alter table 表名 drop primary key;(因为一个表只有一个主键索引,不用去指定索引名)

  4. 修改索引

    先删除再创建

使用索引的注意事项:

  • 占用磁盘空间
  • 对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存储:数据变化频繁,不需要入库,同时又频繁的查询和修改。

myisaminnodb的区别

  • 事务安全:innodb事务安全
  • 查询和添加:myisam查询添加快
  • 全文索引:仅适合于myisam
  • 锁机制:myisam表锁,innodb行锁
  • 外键:myisam不支持外键
  • 定时清理:myisam需要定时整理:optimize table 表名
数据库引擎区别