MySQL核心要点整理

一、MySQL概述

MySQL是一个开源的关系型数据库管理系统,现在属于Oracle公司。随着MySQL功能的不断完善,性能不断提高,又有开源免费的优势,越来越多的企业选择使用MySQL,而放弃商用收费的Oracle。

1.Mysql客户/服务器体系结构

1) 一个是MySQL服务器程序,指的是mysqld程序,运行在数据库服务器上,负责在网络上监听并处理来自客户端的服务请求根据这些请求去访问数据库的内容,再把有关信息回传给客户; 2)另一个程序是MySQL客户端程序,负责连接到数据库服务器,并通过发出命令来告知服务器它想要的操作。

2.Mysql的三层逻辑结构

 

1)最上层是连接层,比如连接处理、授权认证、安全等; 2)第二层包括MySQL的很多核心服务功能(查询缓存、解析器、优化器),包括查询解析、分析、优化、缓存以及所有的内置函数(例如,日期、时间、数学和加密函数),所有的跨存储引擎的功能都在这一层实现:存储过程、触发器、视图等。 3) 第三层包含了存储引擎,存储引擎负责MySQL中数据的存储和提取,是数据库中非常重要非常核心的部分,也是MySQL区别与其他数据库的一个重要特性。

不同的存储引擎有各自的特点,MySQL支持插入式的存储引擎,可以根据实际情况选择最合适的存储引擎。MySQL默认的存储引擎InnoDB应该就是其最佳选择。

3.MySQL的体系结构

从上到下依次是:1) 连接池组件 2) 管理服务和工具组件、SQL接口组件、查询分析器组件、优化器组件、缓冲组件 3) 插件式存储引擎 4)物理文件

4.数据库和实例

1)数据库指物理上的存储文件,实例是用来操作数据库文件的。2)实例指MySQL数据库由后台线程以及一个共享内存区组成。

在MySQL数据库中,实例与数据库通常是一一对应的,这时两个词可以互换,但在集群情况下,可能存在一个数据库被对个数据实例使用的情况。MySQL是单进程多线程架构的数据库,实例在系统上的表现就是一个进程。

5.数据库中事务的四大特性和隔离级别

1)数据库的事务。是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是不可分割的一个序列。在并发访问情况下,可能会出现脏读、不可重复读和幻读等读现象,为了应对这些问题,主流数据库都提供了锁机制,并引入了事务隔离级别的概念。

如果一个数据库支持事务的操作,那么该数据库必须要具备四个特性(ACID):

2)原子性。原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。

3) 一致性。一个事务执行之前和执行之后都必须处于一致性状态。

4) 隔离性。当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。事务的隔离性数据库提供了多种隔离级别。

5)持久性。指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的。

6.不考虑事务的隔离性产生的3种问题

  当多个线程都开启事务操作数据库中的数据时,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性,如果不考虑事务的隔离性,会发生的几种问题:

1) 脏读。指在一个事务处理过程里读取了另一个未提交的事务中的数据。当一个事务正在多次修改某个数据,而在这个事务中这多次的修改都还未提交,这时一个并发的事务来访问该数据,就会造成两个事务得到的数据不一致。

2)不可重复读。指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。

3)虚读(幻读)。是事务非独立执行时发生的一种现象。例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。幻读和不可重复读都是读取了另一条已经提交的事务,所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体。

7.MySQL数据库提供的四种隔离级别

  1)串行化:可避免脏读、不可重复读、幻读的发生。

  2)可重复读:可避免脏读、不可重复读的发生。

  3)读已提交:可避免脏读的发生。

  4)读未提交:最低级别,任何情况都无法保证。

  以上四种隔离级别最高的是串行化级别,最低的是读未提交级别,级别越高,执行效率就越低。像串行化这样的级别,就是以锁表的方式使得其他的线程只能在锁外等待,平时选用何种隔离级别应该根据实际情况。在MySQL数据库中默认的隔离级别为可重复读。

  在MySQL数据库中,支持上面四种隔离级别,默认的为可重复读;而在Oracle数据库中,只支持串行化级别和读已提交这两种级别,其中默认的为读已提交级别。

8.数据库锁机制

当并发事务同时访问一个资源时,有可能导致数据不一致,因此需要一种机制来将数据访问顺序化,以保证数据的一致性。锁就是其中的一种机制。

1)按锁的粒度划分:可分为表级锁、行级锁、页级锁(mysql)。

2)按锁的级别划分:可分为共享锁、排他锁。

3)按使用方式划分:可分为乐观锁、悲观锁。

9.表级锁、行级锁和页级锁

1)行级锁。是Mysql中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁。行级锁能大大减少数据库操作的冲突。其加锁粒度最小,但加锁的开销也最大。行级锁分为共享锁和排他锁。特点:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

2)表级锁。锁是MySQL中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分MySQL引擎支持。最常使用的MYISAM与INNODB都支持表级锁定。表级锁定分为共享锁和排他锁。特点:开销小,加锁快;不会出现死锁;锁定粒度大,发出锁冲突的概率最高,并发度最低。

3)页级锁。是MySQL中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。BDB支持页级锁。特点:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。

10.MySQL常用存储引擎的锁机制

1)MyISAM和MEMORY采用表级锁。

2)BDB采用页级锁或表级锁,默认为页级锁。

3)InnoDB支持行级锁和表级锁,默认为行级锁。

4)行锁实现原理:在Innodb引擎中既支持行锁也支持表锁,InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的。InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁。行级锁都是基于索引的,如果一条SQL语句用不到索引会使用表级锁。行级锁的缺点是:由于需要请求大量的锁资源,所以速度慢,内存消耗大。

11.行级锁与死锁

1)MyISAM中是不会产生死锁的,因为MyISAM总是一次性获得所需的全部锁,要么全部满足,要么全部等待。而在InnoDB中,锁是逐步获得的,就造成了死锁的可能。

2)在MySQL中,行级锁并不是直接锁记录,而是锁索引。索引分为主键索引和非主键索引两种,如果一条sql语句操作了主键索引,MySQL就会锁定这条主键索引;如果一条语句操作了非主键索引,MySQL会先锁定该非主键索引,再锁定相关的主键索引。 在UPDATE、DELETE操作时,MySQL不仅锁定WHERE条件扫描过的所有索引记录,而且会锁定相邻的键值,即所谓的next-key locking。

3)死锁:当两个事务同时执行,一个锁住了主键索引,在等待其他相关索引。另一个锁定了非主键索引,在等待主键索引。这样就会发生死锁。发生死锁后,InnoDB一般都可以检测到,并使一个事务释放锁回退,另一个获取锁完成事务。

4)避免死锁:1.如果不同程序会并发存取多个表,尽量约定以相同的顺序访问表,可以大大降低死锁机会。2.在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率;3.对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率;

12.共享锁和排他锁

1)共享锁。又称读锁,是读取操作创建的锁。其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有共享锁。如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据。用法:SELECT ... LOCK IN SHARE MODE。

在查询语句后面增加LOCK IN SHARE MODE,Mysql会对查询结果中的每行都加共享锁,当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请共享锁,否则会被阻塞。其他线程也可以读取使用了共享锁的表,而且这些线程读取的是同一个版本的数据。

2)排他锁.又称写锁,如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。用法:SELECT ... FOR UPDAT。

在查询语句后面增加FOR UPDATE,Mysql会对查询结果中的每行都加排他锁,当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请排他锁,否则会被阻塞。

对于insert、update、delete,InnoDB会自动给涉及的数据加排他锁;对于一般的Select语句,InnoDB不会加任何锁,事务可以通过以下语句显示加共享锁或排他锁。

13.InnoDB两个表锁-意向锁

意向共享锁(IS)和意向排他锁(IX),意向锁是InnoDB自动加的,不需要用户干预。

1)意向共享锁:表示事务准备给数据行加入共享锁,也就是说一个数据行加共享锁前必须先取得该表的IS锁。

2)意向排他锁:表示事务准备给数据行加入排他锁,说明事务在一个数据行加排他锁前必须先取得该表的IX锁。

14.乐观锁和悲观锁

1)悲观锁。指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度。因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。缺点:悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。

2)乐观锁。采取了更加宽松的加锁机制。大多是基于数据版本记录机制实现。数据版本为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个 “version” 字段来实现。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。

15.MySQL引擎ISAM和InnoDB

 MySQL数据库引擎取决于MySQL在安装的时候是如何被编译的。要添加一个新的引擎,就必须重新编译MYSQL。MYSQL支持引擎:ISAM、MYISAM和HEAP、INNODB和BERKLEY(BDB)。

1)ISAM:是一个定义明确且历经时间考验的数据表格管理方法,它在设计之时就考虑到数据库被查询的次数要远大于更新的次数。因此,ISAM执行读取操作的速度很快,而且不占用大量的内存和存储资源。两个主要不足之处:它不支持事务处理,也不能够容错:如果你的硬盘崩溃了,那么数据文件就无法恢复了。

2)MyISAM:是MySQL的ISAM扩展格式和默认的数据库引擎。除了提供ISAM里所没有的索引和字段管理的大量功能,MyISAM还使用一种表格锁定的机制,来优化多个并发的读写操作,其代价是你需要经常运行OPTIMIZE TABLE命令,来恢复被更新机制所浪费的空间。

MYISAM强调了快速读取操作,MyISAM格式的重要缺陷:不能在表损坏后恢复数据、不支持事务处理、不支持外键。

3)HEAP:允许只驻留在内存里的临时表格。驻留在内存里让HEAP要比ISAM和MYISAM都快,但是它所管理的数据是不稳定的,而且如果在关机之前没有进行保存,那么所有的数据都会丢失。

4)InnoDB:给MySQL提供了具有提交、回滚和崩溃恢复能力的事务安全存储引擎。InnoDB锁定在行级并且也在SELECT语句提供一个Oracle风格一致的非锁定读。尽管要比ISAM和MyISAM引擎慢很多,但是InnoDB包括了对事务处理和外键的支持。

InnoDB是为处理巨大数据量时的最大性能设计,它的CPU效率可能是任何其它基于磁盘的关系数据库引擎所不能匹敌的。

5)适用场景:MyISAM适合:(1)做很多count 的计算;(2)插入不频繁,查询非常频繁;(3)没有事务。InnoDB适合:(1)可靠性要求比较高,或者要求事务;(2)表更新和查询都相当的频繁,并且表锁定的机会比较大的情况。

16.MySQL 主从复制的原理和配置

1)主从复制的原理:分为同步复制和异步复制,实际复制架构中大部分为异步复制。 复制的基本过程如下:1.Slave上面的IO进程连接上Master,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容;2.Master接收到来自Slave的IO进程的请求后,通过负责复制的IO进程根据请求信息读取指定日志指定位置之后的日志信息,返回给Slave的IO进程。返回信息中除了日志所包含的信息之外,还包括本次返回的信息已经读取到Master端的bin-log文件的名称以及bin-log的位置;3.Slave的IO进程接收到信息后,将接收到的日志内容依次添加到Slave端的relay-log文件的最末端,并将读取到的Master 端的 bin-log的文件名和位置记录到master-info文件中,以便在下一次读取的时候能够清楚的告诉Master“我需要从某个bin-log的哪个位置开始往后的日志内容,请发给我”;4.Slave的Sql进程检测到relay-log中新增加了内容后,会马上解析relay-log的内容成为在Master端真实执行时候的那些可执行的内容,并在自身执行。

17.Mysql索引会失效的几种情况分析

1)如果条件中有or

2)对于组合索引,不是使用的第一部分,则不会使用索引

3)like查询是以%开头

4)如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引

5)如果mysql估计使用全表扫描要比使用索引快,则不使用索引

18.MySQL索引类型总结和使用技巧以及注意事项

1)索引。是帮助MySQL高效获取数据的数据结构。索引的本质:是一种数据结构。

2)索引分类.⑴普通索引:这是最基本的索引,它没有任何限制。⑵唯一索引:它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。⑶ 主键索引:它是一种特殊的唯一索引,不允许有空值。一般是在建表的时候同时创建主键索引。⑷组合索引:一个索引包含多个列。例:在 usernname,city,age上建立组合索引,其实是相当于分别建立了下面三组组合索引:usernname,city,age usernname,city usernname,MySQL组合索引采用“最左前缀”。

3)建立索引的时机。一般来说,在WHERE和JOIN中出现的列需要建立索引,MySQL只对<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE才会使用索引,在以通配符%和_开头作查询时,MySQL不会使用索引。

4)索引的不足之处。

1.虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。

2.建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果你在一个大表上创建了多种组合索引,索引文件的会膨胀很快。

5)使用索引的注意事项。

1.索引不会包含有NULL值的列:只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL。

2.使用短索引:短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。

3.索引列排序:MySQL查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。

4.like语句操作:一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而like “aaa%”可以使用索引。

5.不要在列上进行运算:select * from users where YEAR(adddate)<2007;将在每个行上进行运算,这将导致索引失效而进行全表扫描

6.不使用NOT IN和<>操作

6)索引结构。MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等。

数据库查询最基本的查询算法是顺序查找(linear search)时间复杂度为O(n),在数据量很大时效率很低。优化的查找算法如二分查找(binary search)、二叉树查找(binary tree search)等,查找效率提高了,但数据本身的组织结构不可能完全满足各种数据结构。所以,在数据之外,数据库系统还维护着满足特定查找算法的数据结构。这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构就是索引。

7)B-Tree和B+Tree。

目前大部分数据库系统及文件系统都采用B-Tree或其变种B+Tree作为索引结构。

索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。索引查找过程中就要产生磁盘I/O消耗,相对于内存存取,I/O存取的消耗要高几个数量级,所以索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数。

8)内存和磁盘存取原理。

9)主存存取原理。

计算机使用的主存基本都是随机读写存储器(RAM),从抽象角度看,主存是一系列的存储单元组成的矩阵,每个存储单元存储固定大小的数据。每个存储单元有唯一的地址,这里将其简化成一个二维地址:通过一个行地址和一个列地址可以唯一定位到一个存储单元。图一展示了一个4 x 4的主存模型。

10)主存的存取过程如下:

当系统需要读取主存时,则将地址信号放到地址总线上传给主存,主存读到地址信号后,解析信号并定位到指定存储单元,然后将此存储单元数据放到数据总线上,供其它部件读取。写主存的过程类似,系统将要写入单元地址和数据分别放在地址总线和数据总线上,主存读取两个总线的内容,做相应的写操作。主存存取的时间仅与存取次数呈线性关系。

11)磁盘存取原理

索引一般以文件形式存储在磁盘上,索引检索需要磁盘I/O操作。磁盘I/O存在机械运动耗费,因此磁盘I/O的时间消耗是巨大的。

磁盘的整体结构磁盘、磁头、磁头支架:图二是磁盘的整体结构示意图,一个磁盘由大小相同且同轴的圆形盘片组成,磁盘可以转动(各个磁盘必须同步转动)。在磁盘的一侧有磁头支架,磁头支架固定了一组磁头,每个磁头负责存取一个磁盘的内容。磁头不能转动,但是可以沿磁盘半径方向运动(实际是斜切向运动)。

磁盘结构磁道、柱面、扇区:图三是磁盘结构的示意图,盘片被划分成一系列同心环,圆心是盘片中心,每个同心环叫做一个磁道,所有半径相同的磁道组成一个柱面。磁道被沿半径线划分成一个个小的段,每个段叫做一个扇区,每个扇区是磁盘的最小存储单元。假设磁盘只有一个盘片和一个磁头。

磁盘数据读取寻道、寻道时间、旋转时间:当需要从磁盘读取数据时,系统会将数据逻辑地址传给磁盘,磁盘的控制电路按照寻址逻辑将逻辑地址翻译成物理地址,即确定要读的数据在哪个磁道,哪个扇区。为了读取这个扇区的数据,需要将磁头放到这个扇区上方,为了实现这一点,磁头需要移动对准相应磁道,这个过程叫做寻道,所耗费时间叫做寻道时间,然后磁盘旋转将目标扇区旋转到磁头下,这个过程耗费的时间叫做旋转时间。

局部性原理与磁盘预读

由于存储介质的特性,磁盘本身存取就比主存慢很多,再加上机械运动耗费,磁盘I/O的时间消耗是巨大的,为了提高效率,要尽量减少磁盘I/O。为了达到这个目的,磁盘每次都会预读,即使只需要一个字节,磁盘也会从这个位置开始,顺序向后读取一定长度的数据放入内存。这样做的理论依据是计算机科学中著名的局部性原理:当一个数据被用到时,其附近的数据也通常会马上被使用。程序运行期间所需要的数据通常比较集中。磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),因此对于具有局部性的程序来说,预读可以提高I/O效率。预读的长度一般为页(page)的整倍数。页是计算机管理存储器的逻辑块,硬件及操作系统往往将主存和磁盘存储区分割为连续的大小相等的块,每个存储块称为一页(在许多操作系统中,页得大小通常为4k),主存和磁盘以页为单位交换数据。当程序要读取的数据不在主存中时,会触发一个缺页异常,此时系统会向磁盘发出读盘信号,磁盘会找到数据的起始位置并向后连续读取一页或几页载入内存中,然后异常返回,程序继续运行。

12)B-/+Tree索引的性能分析

从使用磁盘I/O次数评价索引结构的优劣性:根据B-Tree的定义,可知检索一次最多需要访问h个结点。数据库系统的设计者巧妙的利用了磁盘预读原理,将一个结点的大小设为等于一个页面,这样每个结点只需要一次I/O就可以完全载入。为了达到这个目的,在实际实现B-Tree还需要使用如下技巧:每次新建结点时,直接申请一个页面的空间,这样可以保证一个结点的大小等于一个页面,加之计算机存储分配都是按页对齐的,就实现了一个node只需一次I/O。综上所述,用B-Tree作为索引结构效率是非常高的。

而红黑树结构,由于逻辑上很近的结点(父子结点)物理上可能离得很远,无法利用局部性原理。所以即使红黑树的I/O渐进复杂度也为O(h),但是查找效率明显比B-Tree差得多。

13)MySQL索引实现

在MySQL中,不同存储引擎对索引的实现方式是不同的。MyISAM的索引方式叫做“非聚集”的,与InnoDB的聚集索引区分。

MyISAM引擎使用B+Tree作为索引结构,叶结点的data域存放的是数据记录的地址。图三图四是MyISAM索引的原理图:

这里设表一共有三列,假设我们以Col1为主键,则图8是一个MyISAM表的主索引(Primary key)示意。可以看出MyISAM的索引文件仅仅保存数据记录的地址。在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复。

InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同。

第一个重大区别是InnoDB的数据文件本身就是索引文件。在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶结点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。

图五是InnoDB主索引(同时也是数据文件)的示意图,可以看到叶结点包含了完整的数据记录。这种索引叫做聚集索引。因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。

第二个与MyISAM索引的不同是InnoDB的辅助索引data域存储相应记录主键的值而不是地址,InnoDB的所有辅助索引都引用主键作为data域。

图六为定义在Col3上的一个辅助索引。聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。为什么不建议使用过长的字段作为主键?因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大。为什么不建议用非单调的字段作为主键?因为InnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,而使用自增字段作为主键则是一个很好的选择。

MySQL的优化主要分为结构优化(Scheme optimization)和查询优化(Query optimization)。

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值