MySQL 事务主要用于处理操做量大,复杂度高的数据。好比说,在人员管理系统中,你删除一我的员,你既须要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操做语句就构成一个事务!mysql
• 在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。• 事务处理能够用来维护数据库的完整性,保证成批的 SQL 语句要么所有执行,要么所有不执行。• 事务用来管理 insert,update,delete 语句通常来讲,事务是必须知足4个条件(ACID)::原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。• 原子性:一个事务(transaction)中的全部操做,要么所有完成,要么所有不完成,不会结束在中间某个环节。事务在执行过程当中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务历来没有执行过同样。• 一致性:在事务开始以前和事务结束之后,数据库的完整性没有被破坏。这表示写入的资料必须彻底符合全部的预设规则,这包含资料的精确度、串联性以及后续数据库能够自发性地完成预约的工做。• 隔离性:数据库容许多个并发事务同时对其数据进行读写和修改的能力,隔离性能够防止多个事务并发执行时因为交叉执行而致使数据的不一致。事务隔离分为不一样级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。• 持久性:事务处理结束后,对数据的修改就是永久的,即使系统故障也不会丢失
MySQL索引的创建对于MySQL的高效运行是很重要的,索引能够大大提升MySQL的检索速度。打个比方,若是合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一我的力三轮车。拿汉语字典的目录页(索引)打比方,咱们能够按拼音、笔画、偏旁部首等排序的目录(索引)快速查找到须要的字。索引分单列索引和组合索引。单列索引,即一个索引只包含单个列,一个表能够有多个单列索引,但这不是组合索引。组合索引,即一个索引包含多个列。建立索引时,你须要确保该索引是应用在 SQL 查询语句的条件(通常做为 WHERE 子句的条件)。实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。上面都在说使用索引的好处,但过多的使用索引将会形成滥用。所以索引也会有它的缺点:虽然索引大大提升了查询速度,同时却会下降更新表的速度,如对表进行INSERT、UPDATE和DELETE。由于更新表时,MySQL不只要保存数据,还要保存一下索引文件。创建索引会占用磁盘空间的索引文件。面试
上面讲了索引的基本原理,数据库的复杂性,以及操做系统的一些内容,目的就是让你们了解到,任何一种数据结构都不是凭空产生的,必定有它的背景和使用场景。那么,咱们须要这些数据结构可以作什么呢?其实很简单,就是:每次查找数据的时候,把磁盘I/O次数限制在一个很小的数量级,最好是一个常量数量级。那么咱们就想到,若是一个高度可控的多路搜索树,是否可以知足需求呢?在这样的背景下,B+树应运而生。sql
如上图,是一棵B+树。B+树的定义,童鞋能够自行百度,咱们只说一些重点。图中浅蓝色的块,咱们称之为一个磁盘,能够看到,每一个磁盘块包含几个数据项(深蓝色)和指针(黄色)。如:磁盘块1包含数据17和数据35,包含指针P1,P2,P3,P1指向数据小于17的磁盘块,P2指向数据在17到35之间的数据所在磁盘块,P3指向数据大于35的数据所在的磁盘块。真实数据存在于叶子节点,即3,5,9,10,13,15,28,29,36,60,75,79,90,99 。非叶子节点不存储真实数据,只存储指引搜索方向的数据项,如1七、35并不真实存在于数据表中。数据库
仍是使用上面的B+树。假设,咱们要查找数据项29,那么咱们首先会把磁盘块1由磁盘加载到内存中,此时进行了一次I/O,在内存中用二分查找肯定29在17和35之间,锁定磁盘块1的P2指针,内存计算时间因为很是短(对比于I/O)能够忽略不计,经过磁盘块1的P2指针的磁盘地址指向磁盘块3,由磁盘加载到内存,此时进行了第二次I/O,29在26和30之间,锁定磁盘块3的P2指针,经过指针加载磁盘块8到内存,此时进行了第三次I/O,同时内存中计算二分查找找到29,查询结束。这一过程,一共进行了3次I/O。在真实使用场景中,三层的B+树能够表示上百万的数据,若是上百万的数据查询只须要三次I/O,性能提升将会是巨大的。B+树就是一种索引数据结构,若是没有这样的索引,每一个数据项发生一次I/O,那么成本将会大大提高。数据结构
在上面的查找例子中,咱们能够分析出一些B+树的性质:架构
1,I/O的次数取决于B+树的高度H,假设当前数据表的数据为N,每一个磁盘块的数据项的数量是M,则有:H=log(M+1)N,当数据量N必定的状况下,M越大,H越小;而M=磁盘块大小/数据项大小,磁盘块大小也就是一个数据页的大小,是固定的,若是数据项占的空间越小,数据项的数量越多,树的高度也就越低。这也就是为何每一个数据项,即索引字段要尽可能的小,好比int占4个字节,要比bigint的8个字节小一半。这也是为何B+树要求把真实数据放在叶子节点内而不是内层节点内,一旦放到内层节点内,磁盘块的数据项会大幅度的降低,致使树层级的增高。当数据项为1时,B+树会退化成线性表。并发
2,B+树的数据项是复合性数据结构,好比(name,age,gender)的时候,B+树是按照从左到右的顺序来创建搜索树的,好比当(小张,22,女)这样的数据来检索的时候,B+树会优先比较name来肯定下一步的搜索方向,若是name相同再依次比较age和gender,最后获得检索的数据。可是,当(22,女)这样没有name的数据来的时候,B+树就不知道下一步该查哪一个节点,由于创建搜索树的时候,name就是第一个比较因子,必须根据name来搜索才知道下一步去哪里查询。好比,当(小张,男)这样的数据来检索时,B+树就能够根据name来指定搜索方向,但下一字段age缺失,因此只能把名字是“小张”的全部数据都找到,而后再匹配性别是“男”的数据了。这个是很是重要的一条性质,即索引的最左匹配特性。oracle
在MySQL中,索引分为两大类:聚簇索引和非聚簇索引。聚簇索引是按照数据存放的物理位置为顺序的,而非聚簇索引则不一样;聚簇索引可以提升多行检索的速度,而非聚簇索引则对单行的检索速度很快。数据库设计
在这两大类的索引类型下,还能够将索引分红四个小类:函数
1,普通索引:最基本的索引,没有任何限制,是咱们大多数状况下使用到的索引。
2,惟一索引:与普通索引类型,不一样的是惟一索引的列值必须惟一,但容许为空值。
3,全文索引:全文索引(FULLTEXT)仅能够适用于MyISAM引擎的数据表;做用于CHAR、VARCHAR、TEXT数据类型的列。
4,组合索引:将几个列做为一条索引进行检索,使用最左匹配原则。
咱们回头来看一开始提到的慢查询,当咱们了解完索引原理以后,对慢查询的优化应该有一些想法,这里咱们先总结一下创建索引的一些原则:
1,最左前缀匹配原则。这是很是重要、很是重要、很是重要(重要的事情说三遍)的原则,MySQL会一直向右匹配直到遇到范围查询(>,<,BETWEEN,LIKE)就中止匹配,好比:a = 1 AND b = 2 AND c > 3 AND d = 4,若是创建 (a,b,c,d)顺序的索引,d是用不到索引的,若是创建(a,b,d,c)的索引,则均可以用到,a,b,d的顺序能够任意调整。
2,等于(=)和in 能够乱序。好比,a = 1 AND b = 2 AND c = 3 创建(a,b,c)索引能够任意顺序,MySQL的查询优化器会帮你优化成索引能够识别的模式。
3,尽可能选择区分度高的列做为索引,区分度的公式是 COUNT(DISTINCT col) / COUNT(*)。表示字段不重复的比率,比率越大咱们扫描的记录数就越少,惟一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度是0。可能有人会问,这个比率有什么经验么?使用场景不一样,这个值也很难肯定,通常须要JOIN的字段咱们要求在0.1以上,即平均1条扫描10条记录。
4,索引列不能参与计算,尽可能保持列“干净”。好比,FROM_UNIXTIME(create_time) = ‘2016-06-06’ 就不能使用索引,缘由很简单,B+树中存储的都是数据表中的字段值,可是进行检索时,须要把全部元素都应用函数才能比较,显然这样的代价太大。因此语句要写成 :create_time = UNIX_TIMESTAMP(‘2016-06-06’)。
5,尽量的扩展索引,不要新创建索引。好比表中已经有了a的索引,如今要加(a,b)的索引,那么只须要修改原来的索引便可。
6,单个多列组合索引和多个单列索引的检索查询效果不一样,由于在执行SQL时,MySQL只能使用一个索引,会从多个单列索引中选择一个限制最为严格的索引。
根据上面这些原则,咱们来修改开篇的慢查询:
SELECTcount(*) AS countFROM trade_bASe AS aWHEREa.trade_status = 7 AND a.create_time BETWEEN '2015-09-01' AND '2016-01-14' AND a.booking_source = '2'
根据这条SQL,应该创建的索引是:trade_status, booking_source,create_time的联合索引;其中,trade_status、booking_source的顺序能够颠倒,并且 create_time 的区间查询放到后面。这就是利用了索引的最左匹配原则。这一点和oracle恰好相反,oracle是从右到左
1,查看运行效果,是否真的很慢,主要设置SQL_NO_CACHE。
2,WHERE条件单表查询,锁定最小返回记录表。这句话的意思是,把查询语句的WHERE都应用到表中返回的记录数最小的表开始查起,单表每一个字段分别查询,看哪一个字段的区分度最高
3,EXPLAIN查看执行计划,是否与1预期一致(从锁定记录较少的表开始查询)
4,ORDER BY LIMIT 形式的SQL语句,让排序的表优先查
5,多去了解业务的使用场景
6,加索引时,要参照创建索引的几大原则
7,观察结果,不符合预期,则从新从1开始分析。
1,什么时候使用聚簇索引或非聚簇索引:
2,索引不会包含有NULL值的列:只要列中包含有NULL值,都将不会被包含在索引中,组合索引中只要有一列有NULL值,那么这一列对于此条组合索引就是无效的。因此咱们在数据库设计时,不要让索引字段的默认值为NULL。
3,使用短索引:假设,若是有一个数据类型为CHAR(255)的列,在前10个或20个字符内,绝大部分数据的值是惟一的,那么就不要对整个列进行索引。短索引不只能够提升查询速度并且能够节省I/O操做。
4,索引列排序:MySQL查询只使用一个索引,所以若是WHERE子句中已经使用了索引的话,那么ORDER BY中的列是不会使用索引的。所以数据库默认排序能够符合要求的状况下,不要使用排序操做;尽可能不要包含多个列的排序,若是须要,最好给这些列也建立组合索引。
5,LIKE语句操做:通常状况下,不建议使用LIKE操做;若是非使用不可,如何使用也是一个研究的课题。LIKE “%aaaaa%”不会使用索引,可是LIKE “aaa%”却可使用索引。
6,不要在索引列上进行运算:在创建索引的原则中,提到了索引列不能进行运算,这里就再也不赘述了。
最后,总结一下,其实任何数据库层面的优化,都抵不上应用系统的优化,一样是MySQL,Facebook/Google等等均可以支撑,因此且行且珍惜吧!
前段时间,有个大佬面上了某大厂,送给我一批学习资料,整理出来,就造成了如下文档(数据库方面),主要包括MySQL面试题、MySQL基础到高级到调优笔记、MySQL知识总结、MySQL性能调优与架构设计解析文档,已打包好
添加小助手VX:xuanwo008便可获取~
因为篇幅字数缘由,在这只展现详细目录及内容的截图了,有须要的朋友添加小助手VX:xuanwo008便可获取~