个人对于选择存储引擎,建表,建索引,sql优化的一些总结,给读者提供一些参考意见

推荐访问我的个人网站,排版更好看: https://chenmingyu.top/mysql-optimize/

存储引擎

mysql中查看支持的引擎的sql:

show engines;

日常工作中使用较多的存储引擎对比:InnoDB,MyISAM

InnoDB MyISAM
存储限制 64T 256T
支持事务 yes no
支持索引 yes yes
支持全文索引 no yes
支持数据缓存 yes no
支持外键 yes no
支持Hash索引 no no
innodb

支持提交、回滚和崩溃恢复能力的事物安全(ACID),支持行锁,支持外键完整性约束

适合场景

  • 需要事务处理
  • 表数据量大,高并发操作
MyISAM

MyISAM存储引擎提供了高速检索和存储的能力,支持全文索引

适合场景

  • 很多count计算的
  • 查询非常频繁的

其余几种存储引擎

MEMORY引擎

数据只保存在内存中,因为是在内存中,拥有极高的插入,更新,查询的效率,但是重启后数据都会丢失,表级锁,并发性能低。

MERGE引擎

merge表是一组MyISAM表的组合,所以merge表是没有数据的,对这个表的操作实际上是操作内部的MyISAM表,将多个MyISAM表合并适合做一些报表之类的操作。

ARCHIVE引擎

仅支持插入和查询,使用zlib压缩库,在记录被请求的时候实时压缩,不支持事务,支持行级锁,适合存储大量的日志数据。

个人是推荐Innodb引擎的,公司部门里也是规定新建表的时候必须使用Innodb引擎,Innodb引擎较MyISAM引擎可以提供更多的功能,不是很实时的查询场景可以使用缓存,近实时的查询可以使用es,当然了这只是个人看法,针对不同的场景选择不同的存储引擎还是很有必要滴。所以在知道不同存储引擎的特性之后,才可以根据不同业务需求选择合适的存储引擎。

建表原则

在建表的时候尽量遵循以下原则
  1. 尽量选择小的数据类型,数据类型选择上尽量tinyint(1字节)>smallint(2字节)>int(4字节)>bigint(8字节),比如逻辑删除yn字段上(1代表可用,0代表)就可以选择tinyint(1字节)类型

  2. 尽量保证字段数据类型长度固定

  3. 尽量避免使用null,使用null的字段查询很难优化,影响索引,可以使用0或''代替

  4. 避免宽表,能拆分就拆分,一个表往往跟一个实体域对应,就像设计对象的时候一样,保持单一原则

  5. 尽量避免使用text和blob,如果非使用不可,将类型为text和blob的字段在独立成一张新表,然后使用主键对应原表

  6. 禁止使用float或double类型,这个坑超大,float或double存在精度问题,在进行比较或者加减操作的时候会丢失精度导致数据异常,凡是使用float或double类型的时候考虑下可不可使用int或bigint代替。比如金额,以元为单位使用float或double类型的时候,可以考虑以分为单位使用int,bigint类型代替,然后由业务代码进行单位的转换。

  7. 每张表都加上createUser,createTime.updateUser,updateTime字段

  8. 起名字要规范,包括:库名,表名,字段名,索引名

  9. 查询频繁使用的字段记得加索引

  10. 尽量避免使用外键,不用外键约束,性能更高,然后数据的完整性有程序进行管理

  11. 如果表的数量可以预测到非常大,最好在建表的时候,就进行分表,不至于一时间数据量非常大导致效率问题

    未完待补充,,,

索引

索引是为来加速对表中数据行中的检索而创建的一种分散的数据结果,是针对表而建立的,它是由数据页面以外的索引页面组成,每个索引页中的行都含有逻辑指针,以便加速检索物理数据,创建索引的目的在于提高查询效率,innodb的索引都是基于b tree实现的

索引类型

普通索引:最基本的索引,无限制

#方式1
CREATE INDEX idx_username ON sys_user(user_name(32));
#方式2
ALTER table sys_user ADD INDEX idx_username(user_name(32))

主键索引:一个表只能有一个主键索引,且不能为空

一般建表时同时创建了主键索引

CREATE TABLE `sys_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_name` varchar(32) DEFAULT NULL,
`pass_word` varchar(32) DEFAULT NULL,
`token` varchar(32) DEFAULT NULL,
`token_expire` int(11) DEFAULT NULL,
`yn` smallint(6) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=348007 DEFAULT CHARSET=utf8;

唯一索引:与普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一

CREATE UNIQUE INDEX idx_token ON sys_user(token_expire)

组合索引:指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用组合索引时遵循最左前缀集合

ALTER TABLE sys_user ADD INDEX idx_un_te (user_name(32),token_expire);

全文索引:用来查找文本中的关键字,而不是直接与索引中的值相比较。只有char、varchar,text 列上可以创建全文索引

CREATE FULLTEXT INDEX idx_ ON sys_user(pass_word)
创建使用索引的原则
  1. 索引的字段尽量要小,根据索引查询数据的快慢取决于b tree的高度,当数据量恒定的时候,字节越少,存的索引的数量就越多,树的高度就越会越低
  2. 遵循索引的最左匹配原则
  3. 注意使用like的时候尽量不要使用“%a%”,这样的不走索引,可以使用“a%”,走索引
  4. 不要在索引的列上进行计算,比如 select * from sys_user where token_expire+1 = 10000,这样的语句 不会走有索引
  5. 什么样的字段建索引,就是那种频繁在where,group by,order by中出现的列,最好加上索引
索引的缺点

虽然索引的可以提高查询的效率,但是在进行insert,update,和delete的时候会降低效率,因为在保存数据的同时也会去保存索引。

不要在一个表里建过多的索引,问题跟上面一样,在操作数据的时候效率降低,而且数据量少的表要看情况建索引,如果建索引跟没建索引的效果差不多少的情况下就不要建索引了,如果是数据量大的表,就需要建索引去优化查询效率。

explain分析sql

可以使用explain去分析sql的执行情况,比如

explain select * from sys_user where token_expire = 10000;

在阿里的开发手册中提到过,sql性能优化的标准:至少要达到range,要求ref级别,如果可以是consts最好

说明一下,这里的级别指的就是上图的type字段:

  • consts 是指单表中最多只有一个匹配行(主键或唯一索引)
  • ref 指的是使用普通索引
  • range 是指对索引进行范围查询

sql优化

关于sql语句的优化主要是两方面,一个是在建sql的时候需要注意的问题,另一个就是在发现有慢sql的时候可以根据不同情况进行分析,然后优化sql

优化的建议
  1. 查询的时候一定要记得使用limit进行限制

  2. 对于结果只需要一条数据的查询用limit 1进行限制

  3. 使用count(*)来统计行数或者使用count(主键)来查询,使用count(列)的时候,不会统计此列为null的情况

  4. 不要使用select * 来查数据,使用select 需要的列名,这样的方式去查询

  5. 使用join链接代替子查询

  6. 不要使用外键,外键的约束可以放在程序里解决

  7. 控制一下in操作的集合数量,不要太大了

  8. 针对慢查询使用explain去分析原因,然后优化sql,让其尽量走索引

上面说的四个方面就是我目前对于sql优化各个方面的注意事项,希望可以给大家提供一个参考,有问题的可以指出来,交流交流

mysql优化 | 存储引擎,建表,索引,sql的优化建议的更多相关文章

  1. Mysql不同存储引擎的表转换方法

    Mysql不同存储引擎的表转换方法 1.Alter table直接修改表的存储引擎,但是这样会导致大量的系统开销,Mysql为此要执行一个就表向新表的逐行复制.在此期间,转换操作可能会占用服务器的所有 ...

  2. MySQL InnoDB存储引擎体系架构 —— 索引高级

    转载地址:https://mp.weixin.qq.com/s/HNnzAgUtBoDhhJpsA0fjKQ 世界上只两件东西能震撼人们的心灵:一件是我们心中崇高的道德标准:另一件是我们头顶上灿烂的星 ...

  3. MySQL之存储引擎(表类型)的选择

    和大部分的数据库不同,MySQL中有一个存储引擎的概念,用户可以根据数据存储的需求来选择不同的存储引擎.本次博客就来介绍一下MySQL中的存储引擎.MySQL版本 5.7.19. 概述 MySQL的存 ...

  4. (转)Mysql技术内幕InnoDB存储引擎-表&索引算法和锁

    表 原文:http://yingminxing.com/mysql%E6%8A%80%E6%9C%AF%E5%86%85%E5%B9%95innodb%E5%AD%98%E5%82%A8%E5%BC% ...

  5. MySQL技术内幕InnoDB存储引擎(表&索引算法和锁)

    表 4.1.innodb存储引擎表类型 innodb表类似oracle的IOT表(索引聚集表-indexorganized table),在innodb表中每张表都会有一个主键,如果在创建表时没有显示 ...

  6. 浅谈MySql的存储引擎(表类型)

    来源:http://www.cnblogs.com/lina1006/archive/2011/04/29/2032894.html 什么是MySql数据库 通常意义上,数据库也就是数据的集合,具体到 ...

  7. 浅谈MySql的存储引擎(表类型) (转)

    什么是MySql数据库 通常意义上,数据库也就是数据的集合,具体到计算机上数据库可以是存储器上一些文件的集合或者一些内存数据的集合. 我们通常说的MySql数据库,sql server数据库等等其实是 ...

  8. (转)浅谈MySql的存储引擎(表类型)

    原文:http://www.cnblogs.com/lina1006/archive/2011/04/29/2032894.html 什么是MySql数据库 通常意义上,数据库也就是数据的集合,具体到 ...

  9. mysql innodb存储引擎的聚集索引

    InnoDB聚集索引 MySQL有没有支持聚集索引,取决于采用哪种存储引擎. MySQL InnoDB一定会建立聚集索引,所谓聚集,指实际数据行和相关的键值保存在一块,这也决定了一个表只能有一个聚集索 ...

  10. MySQL数据库 存储引擎,创建表完整的语法,字段类型,约束条件

    1.存储引擎 - 存储引擎是用于根据不同的机制处理不同的数据. - 查看mysql中所有引擎: - show engines; - myisam: 5.5以前老的版本使用的存储引擎 - blackho ...

随机推荐

  1. Java开发笔记(八十五)通过字符流读写文件

    前面介绍了文件的信息获取.管理操作,以及目录下的文件遍历,那么文件内部数据又是怎样读写的呢?这正是本文所要阐述的内容.File工具固然强大,但它并不能直接读写文件,而要借助于其它工具方能开展读写操作. ...

  2. 在Linux上部署Web项目

    You believe it or not there is a feeling, lifetime all not lost to time. 在Linux上部署Web项目 这个是普通的web项目, ...

  3. Spring Cloud 微服务开发系列整理

    Spring Boot 系列精选 Spring Boot 自定义 starter Spring Boot 整合 mybatis-plus Spring Boot 整合 spring cache Spr ...

  4. [C#学习笔记1]用csc.exe和记事本写一个C#应用程序

    csc.exe是C#的命令行编译器(CSharpCompiler),可以编译C#源程序成可执行程序.它与Visual Studio等IDE(Integrated Development Environ ...

  5. C++ 子类继承父类纯虚函数、虚函数和普通函数的区别

    C++三大特性:封装.继承.多态,今天给大家好好说说继承的奥妙 1.虚函数: C++的虚函数主要作用是“运行时多态”,父类中提供虚函数的实现,为子类提供默认的函数实现.子类可以重写父类的虚函数实现子类 ...

  6. 业务与IT技术

    最近听一个同事又再次提问关于业务比技术重要,是真的吗? 今天我们再来看一下.      一,什么是业务? 业务意指某种有目的的工作或工作项目.技术可以指人类对机器.硬件或人造器皿的运用,但它也可以包含 ...

  7. PMM Client 安装异常报错

    1.PMM架构 如下图所示 2.Client主要组件 PMM Client是安装在你要监视的MySQL或MongoDB主机上的一组代理组件.组件收集关于一般系统和数据库性能的各种数据,并将该数据发送到 ...

  8. 位运算 leecode.389. 找不同

    //给定两个字符串 s 和 t,它们只包含小写字母. //字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母. //请找出在 t 中被添加的字母 char findTheDifferenc ...

  9. Web前端教程-HTML及标签的使用

    目录 1. HTML简介 1.1. HTML文档基本结构 2. 标签 2.1. 标签语法 1.2. 标签的属性和值 1.3. 常见的标签 1. 基础标签 2. 格式标签 3. 表单标签 4. 框架标签 ...

  10. 怪事年年有,今天特别多!org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.BindingException: Parameter 'empno' not found. Available parameters are [emp, deptno, param1, param

    错误: org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.Binding ...