一、存储引擎

  存储引擎,MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同的存储机制、索引技巧、锁定水平并且最终提供广泛的不同的功能和能力。通过选择不同的技术,你能够获得额外的速度或者功能,从而改善你的应用的整体功能。InnoDB存储引擎是5.5版本后Mysql的默认数据库,事务型数据库的首选引擎,支持ACID事务,支持行级锁定。另外还有常见的MyISAM存储引擎,它拥有较高的插入,查询速度,但不支持事务。所以,很明显:插入不频繁,查询非常频繁,没有事务,用MyISAM;可靠性要求高,表更新频繁,事务多,用InnoDB。

//#查看本机MySQL提供的什么存储引擎
//show ENGINES;
//
//#查看Mysql当前默认的存储引擎
//show variables like '%storage_engine%';
//
//#查看当前表用什么存储引擎(DDL最后)
//show create table idc_work_order_main; //#修改当前表的存储引擎
//ALTER TABLE idc_work_order_main ENGINE = 'MyISAM'

  MySQL官方对InnoDB是这样解释的,InnoDB给MySQL提供了具有提交、回滚和奔溃恢复能力的事务安全存储引擎。InnoDB是为处理巨大数据量时的最大性能设计,它的CPU效率可能是任何其它基于磁盘的关系数据库引擎所不能匹敌的。InnoDB存储引擎被完全与MySQL服务器整合,InnoDB存储引擎为在主内存中缓存数据和索引而维持它自己的缓冲池。

  如果使用innodb存储引擎,我们知道该引擎最主要的特点是transactional和row lock(行级锁)。按理说不会出现表锁才对,但是事实上还是会出现锁表的的情况,也会比较严重,下面主要就是来探讨一下这个问题。查看mysql文档会发现,虽然innodb使用的的row lock(行级锁),但是在处理具有auto increment字段的表的时候,会使用一种特殊的表锁:AUTO-INC。简单来说就是Innodb会在内存里保存一个计数器用来记录 auto_increment的值,当插入数据时,就会用一个表锁来锁住这个计数器,直到插入结束。一条一条插入问题不大,但是如果高并发插入,就会造成 sql阻塞。

  解决方案:1.不使用auto increment字段,自己维护主键生成。该方法中选择主键生成策略很重要, 要综合考虑简单和效率问题。假设使用uuid,虽然简单但是会造成该表的主键效率很低(innodb的主键是特殊的index,其他的index会引用主键)。2.升级到最新的5.2版本。

//#MySQL5.1.22版本之前,这种方式的特点就是“表级锁定”,并发性较差
//innodb_autoinc_lock_mode = 0 (“traditional” lock mode:全部使用表锁)
//
//#推荐使用“consecutive”,并发性相对较高,特点是,即保证同一条insert语句中新插入的auto_increment id都是连续的
//innodb_autoinc_lock_mode = 1 (“consecutive” lock mode)
//
//#这种模式是来一个分配一个,而不会锁表,只会锁住分配id的*过程*,和innodb_autoinc_lock_mode = 1的区别在于
//#不会预分配多个,这种方式并发性最高。但是在replication中当binlog_format为statement-based时
//#(简称SBR statement-based replication)存在问题,因为是来一个分配一个,这样当并发执行时,
//#“Bulk inserts”在分配时会同时向其他的INSERT分配,会出现主从不一致(从库执行结果和主库执行结果不一样),因为binlog只会记录开始的 insert id。
//innodb_autoinc_lock_mode = 2 (“interleaved” lock mode:全部使用新方式,不安全,不适合replication)

  关于数据的拷贝问题,常用的数据表引擎是MyISAM和InnoDB。MyISAM的数据表的后缀名是.frm(表结构)、.myd(数据)和.myi(索引),其索引和数据是分开的,可以直接拷贝;InnoDB的数据表的后缀名是.frm(表结构)和.ibd(数据),索引和数据都在同个文件ibdata*,不能直接拷贝,需要先导出再导入。拷贝完之后别忘了重启数据库服务。

    

  既然是存储引擎,那么我们看看这些数据库的存储是什么样的。block是相对于磁盘来讲的,page是相对于内存来讲的。第一幅图是新建一个txt文档,文件写入1,然后再属性中看占用空间的大小,也就是一个block的大小是4k个字节。通过右图的方式可以用来查看内存中页的大小。

              

磁盘是分block块的,同一表的数据页是以链表的形式串联在一起的,数据库数据按行存在各个block中,并且以block为单位来存取数据。执行一条SQL的时候,从命令解析、确定执行计划、增删改查。这样磁盘的I/O带来了性能问题。如何减少磁盘的I/O次数呢?

// 1.保证读取数据量在合理大小
// 2.保证存取数据能够顺序读取
// 3.减少需要扫描数据占用空间

保证读取数据量在合理大小;保证存取数据能够顺序读取;减少需要扫描数据占用空间。解决措施,就是使用index索引。dense index是稠密索引,也叫全索引。sparse index是稀疏索引。dense indexes是通过对每一个record在磁盘上持久保存一些额外的数据,用于提高查询的效率。Sparse index结合sequential file和dense index file的优点,通过保存部分key K作为它的record,能很好的支持二分查找快速查找record,并且能进一步减少所需的磁盘I/O。

                       

二、索引  

  索引是帮助MySQL高效获取数据的数据结构。介绍MySQL的索引结构,索引原理,进而学习索引的优化。MySQL的索引结构包括:B-tree索引、Tree索引、哈希索引(Hash)、位图索引(Bitmap)、跳表。

//#查看表的当前索引  执行结果显示(Index_type: BTREE)
//SHOW INDEX FROM idc_work_order_main

  命令用于查看我们的数据库中表的当前索引,执行结果显示当前表结构使用功能的索引是BTREE。通常我们通过如下方式给表建索引:

//#查询表当前使用的索引(表的主键自动建立唯一索引unique index)
//SHOW INDEX FROM idc_work_order_main;
//
//#创建索引index
//CREATE INDEX aaa ON idc_work_order_main(remark)
//DROP INDEX aaa ON idc_work_order_main
//
//#创建唯一索引unique INDEX(唯一的索引意味着两个行不能拥有相同的索引值,否则创建失败)
//CREATE UNIQUE INDEX aaa ON idc_work_order_main(id)
//DROP INDEX aaa ON idc_work_order_main
//
//#创建组合索引
//CREATE INDEX aaa ON idc_work_order_main(id,remark)
//DROP INDEX aaa ON idc_work_order_main

我们知道索引并不是随便乱建的,在考虑是否建索引时,我们一般考虑如下的一些情况:

  1.表记录太少。如果一个表只有5条记录,采用索引去访问记录的话,那首先需访问索引表,再通过索引表访问数据表,一般索引表与数据表不在同一个数据块,这种情况下至少要往返读取数据块两次。而不用索引的情况下ORACLE会将所有的数据一次读出,处理速度显然会比用索引快。

  2.经常插入、删除、修改的表。对一些经常处理的业务表应在查询允许的情况下尽量减少索引。

  3.数据重复,且分布平均的表字段。假如一个表有10万行记录,有一个字段A只有T和F两种值,且每个值的分布概率大约为50%,那么对这种表A字段建索引一般不会提高数据库的查询速度。

  建立索引,一般是在对针对百万级以上的数据才建立索引的,以期来提高性能。在创建索引时,首先要考虑表空间和磁盘空间是否足够。我们知道索引也是一种数据,在建立索引的时候势必也会占用大量表空间。因此在对一大表建立索引的时候首先应当考虑的是空间容量问题。其次,在对建立索引的时候要对表进行加锁,因此应当注意操作在业务空闲的时候进行。其次考虑因素便是磁盘I/O。物理上应当尽量把索引与数据分散到不同的磁盘上。逻辑上,数据表空间与索引表空间分开。这是在建索引时应当遵守的基本准则。

//一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而like “aaa%”可以使用索引。
//NOT IN和操作都不会使用索引将进行全表扫描。NOT IN可以NOT EXISTS代替,id3则可使用id>3 or id

  索引结构,当前Mysql版本只有BTree和Hash两种索引类型,默认为BTree。Oracle或其他类型数据库中会有Bitmap索引(位图索引)。下面将主要介绍B树索引、哈希索引、位图索引这三种索引结构。

  B树(Blance Tree)索引,数据结构原型是多路搜索树,它是一种常见的数据结构,常用做数据库的索引。使用BTree结构可以显著减少定位记录时所经历的中间过程,从而加快存取速度。

// Blance Tree索引不适合的场景:
// 1.单列索引的列不能包含null的记录,复合索引的各个列不能包含同时为null的记录,否则会全表扫描;
// 2.不适合键值较少的列(重复数据较多的列,is_deleted "y" "n");
// 3.前导模糊查询不能利用索引(like '%XX'或者like '%XX%')

  图片展示了B树索引,在插入和删除的时候,对Blance Tree的影响。

  哈希索引(Hash),Hash散列索引是根据HASH算法来构建的索引。虽然 Hash 索引效率高,但是 Hash 索引本身由于其特殊性也带来了很多限制和弊端,主要有以下这些:精确查找非常快(包括= <> 和in),其检索效率非常高,索引的检索可以一次定位,不像BTree 索引需要从根节点到枝节点,所以 Hash 索引的查询效率要远高于 B-Tree 索引。

// Hash 索引不适合的场景:
// 1.不适合模糊查询和范围查询(包括like,>,<,between……and等),由于 Hash索引比较的是进行 Hash运算之后的 Hash值,所以它只能用于等值的过滤,不能用于基于范围的过滤
// 因为经过相应的 Hash 算法处理之后的 Hash值的大小关系,并不能保证和Hash运算前完全一样;
// 2.不适合排序,数据库无法利用索引的数据来提升排序性能,同样是因为Hash值的大小不确定;
// 3.复合索引不能利用部分索引字段查询,Hash索引在计算 Hash值的时候是组合索引键合并后再一起计算Hash值,而不是单独计算Hash值,
// 所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash 索引也无法被利用。
// 4.同样不适合键值较少的列(重复值较多的列)

  位图索引(Bitmap),就是用位图表示的索引,对列的每个键值建立一个位图。相对于BTree索引,占用的空间非常小,创建和使用非常快。位图索引由于只存储键值的起止Rowid和位图,占用的空间非常少。

如test表中有state这样一列,10行数据如下:

10    20    30    20    10    30    10    30    20    30

那么会建立三个位图,如下:

BLOCK1    KEY=10  1    0    0    0    1    0    1    0    0    0
BLOCK2 KEY=20 1 0 0 0 1 0 1 0 0 0
BLOCK3 KEY=30 1 0 0 0 1 0 1 0 0 0 //位图索引适合场景:
//1.适合决策支持系统;
//2.当select count(XX) 时,可以直接访问索引中一个位图就快速得出统计数据;
//3.当根据键值做and,or或 in(x,y,..)查询时,直接用索引的位图进行或运算,快速得出结果行数据。 //位图索引不适合场景:
//1.不适合键值较多的列(重复值较少的列);
//2.不适合update、insert、delete频繁的列,代价很高。

  跳表,利用了链表的结构图。一个节点存储了下下一个节点的信息,让性能提升了一倍。

三、MySQL优化

  1.limit start, count分页的优化,limit语句的查询时间与起始位置(start)的位置成正比。建议加索引,利用MySQL提供的索引缓存,不要直接去找数据地址,而是去索引地址先去查索引。

  2.表的数据类型,能小就小,能用char(1)就不用varchar。避免使用null,count(列)不统计值为null的行数,且不利于索引。

  3.char是固定大小,varchar可以动态存储数据。优先用tinyint、smallint,再用int、bigint。

  4.在存储相同数值范围的数据时,浮点数类型float通常都会比decimal类型使用更少的空间。float字段使用4字节存储数据。double类型需要8个字节并拥有更高的精确度和更大的数值范围,decimal类型的数据将会转换成double类型。

附录:

1、全文索引,全文索引技术是目前搜索引擎的关键技术。试想在1M大小的文件中搜索一个词,可能需要几秒,在100M的文件中可能需要几十秒,如果在更大的文件中搜索那么就需要更大的系统开销,这样的开销是不现实的所以在这样的矛盾下出现了全文索引技术。InnoDB不支持,Myisam支持性能比较好,一般在 CHAR、VARCHAR 或 TEXT 列上创建。

2.聚集索引,该索引中键值的逻辑顺序决定了表中相应行的物理顺序。 聚集索引确定表中数据的物理顺序。Mysql中myisam表是没有聚集索引的,innodb有(主键就是聚集索引),聚集索引在下面介绍innodb结构的时有详细介绍。

MySQL引擎、索引和优化(li)的更多相关文章

  1. MySQL函数索引及优化

    很多开发人员在使用MySQL时经常会在部分列上进行函数计算等,导致无法走索引,在数据量大的时候,查询效率低下.针对此种情况本文从MySQL5.7 及MySQL8.0中分别进行不同方式的优化. 1. M ...

  2. 理解Mysql的索引与优化

    转自:http://www.cnblogs.com/hustcat/archive/2009/10/28/1591648.html 写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库 ...

  3. MySQL的索引与优化

    写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储100条记录.如果没有索引,查询将 ...

  4. MySQL的索引及其优化

    前言 索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储100条记录.如果没有索引,查询将对整 ...

  5. mysql的索引以及优化

    本人qq群也有许多的技术文档,希望可以为你提供一些帮助(非技术的勿加). QQ群:   281442983 (点击链接加入群:http://jq.qq.com/?_wv=1027&k=29Lo ...

  6. MySQL中索引和优化的用法总结

    1.什么是数据库中的索引?索引有什么作用? 引入索引的目的是为了加快查询速度.如果数据量很大,大的查询要从硬盘加载数据到内存当中. 2.InnoDB中的索引原理是怎么样的? InnoDB是Mysql的 ...

  7. mysql:联合索引及优化

    命名规则:表名_字段名1.需要加索引的字段,要在where条件中2.数据量少的字段不需要加索引3.如果where条件中是OR关系,加索引不起作用4.符合最左原则 尽量不要用or,如果可以用union代 ...

  8. 【mysql】索引的优化

    写在前面的话 查询容易,优化不易,且写且珍惜 mysql结构 从MySQL逻辑架构来看,MySQL有三层架构,第一层连接,第二层查询解析.分析.优化.视图.缓存,第三层,存储引擎 MySQL有哪些索引 ...

  9. Mysql常用索引及优化

    索引是帮助我们快速获取数据的数据结构.索引是在存储引擎中实现的,因此不同存储引擎的索引也不同.这里只介绍InnoDB存储索引所支持的BTree索引: 一.索引类型 为了方便举例子,先创建表person ...

  10. Mysql的索引及优化

    一:四种存储引擎: mysql使用 show engines查询其存储引擎: 功  能 MYISAM Memory InnoDB Archive 存储限制 256TB RAM 64TB None 支持 ...

随机推荐

  1. Android SDK 在线更新镜像服务器资源

    本文转自:http://blog.kuoruan.com/24.html.感谢原作者. 什么是Android SDK SDK:(software development kit)软件开发工具包.被软件 ...

  2. 通过sails和阿里大于实现短信验证

    通过sails与阿里大于来实现注册短信验证码的发送,逻辑图如下 1.用户在客户端发送手机号给服务器,服务器接收到手机号,生成对应时间戳,随机四位数验证码 2.服务器将电话号码和验证码告诉阿里大于服务器 ...

  3. Html 制作相册

    本文主要讲述采用Html5+jQuery+CSS 制作相册的小小记录. 主要功能点: Html5进行布局 调用jQuery(借用官网的一句话:The Write Less, Do More)极大的简化 ...

  4. 安卓客户端a标签长按弹框提示解决办法

    昨天工作时候发现一个bug,是关于a标签的,在安卓客户端中,如果是a标签的话,长按会出现一个弹框,如图所示 是因为安卓客户端的长按触发机制,以后进行wap端开发的时候,如果用到跳转页面尽量不要用a标签 ...

  5. 对Maven、gradle、svn、spring 3.0 fragment、git的想法

    1.Maven Maven可以构建项目,采用pom方式配置主项目和其他需要引用的项目.同时可结合spring3.0的新特性web  fragment. 从现实出发,特别是对于管理不到位,程序员整体素质 ...

  6. hibernate-mapping-3.0.dtd;hibernate-configuration-3.0.dtd;hibernate.properties所在路径

    hibernate-mapping-3.0.dtd 所在路径:hibernate-release-5.2.5.Final\project\hibernate-core\src\main\resourc ...

  7. 我的MYSQL学习心得(八) 插入 更新 删除

    我的MYSQL学习心得(八) 插入 更新 删除 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得( ...

  8. 开源一个WEB版本GEF,基于SVG的网页流程图框架

    8月开始断断续续的制作这个web gef,没有任何依赖,完全原生js开发,目前已经完成了雏形,基本上可以在项目里应用了. 下图展示的是demo1的效果,包括拖拽,生成连线,点击生成\取消墙体,整个de ...

  9. WebEssentials 在vs2013 update5安装报错的解决方法.

    WebEssentials 最高支持到update4 如果更新到了update5 RC, 则无法直接安装. 解决方法是 1,下载WebEssentials2013.vsix 文件. 2, 安装7zip ...

  10. Atitit 图像处理的心得与疑惑 attilax总结

    Atitit 图像处理的心得与疑惑 attilax总结 1.1. 使用类库好不好??还是自己实现算法1 1.2. 但是,如果遇到类库体积太大,后者没有合适的算法,那就只能自己开发算法了1 1.3. 如 ...