索引及InnoDB

https://www.cnblogs.com/jianmianruxin/p/7213690.html  数据库索引

https://www.cnblogs.com/jianmianruxin/p/7238550.html  数据结构及算法

数据如何存储:

表是根据主键顺序组织存放的。而聚集索引就是按照每张表的主键构造一颗B+树,同时叶子节点中存放的即为整张表的行记录数据,也将聚集索引的叶子节点称为数据页。聚集索引的这个特性决定了索引组织表中数据也是索引的一部分。

 

(唯一索引和普通索引区别只是列的值是唯一的)

 

索引页和表页:表行和索引行都被存储在页中,页的大小决定了一个页可以存多少个表行,索引行以及需要多少个页来存储表行和索引行,页的大小一般为4KB.

缓冲池和IO活动都是基于页的,这意味着一次IO会读入多条记录到缓冲池,而不仅仅是一条。

innoDB存储引擎中,表都是根据主键顺序组织存放(因此也叫(主键)索引组织表)。创建表时没显示声明主键,innodb会按如下方式选择或创建:

非空的唯一索引,多个非空的唯一索引时选择第一个定义的非空唯一索引(不是建表时列的顺序)(建表时没有声明主键的情况下至少保证声明至少一个非空的唯一索引)。都不满足的话则创建一个6字节大小的指针。

建表时没有显示定义主键的情况下,可用_rowid查看主键的列的值与其他列对比来确定主键是谁(只能看单列主键):select *,_rowid from base_regions

 

表空间由段组成(行,页,区,段):

数据段即B+树的叶子节点,索引段即B+树的非叶子节点

 

B+树:(树的概念中叶子节点就是终端节点)

 

 

 

 

B+树的非叶子节点(非数据页)只存放key值(key:关键字的值)和指向叶子节点的指针。

含有多行记录的一页就是B+树的一个叶子节点,也就是说,索引只帮你索引到页的层面,具体要找页中的哪些行还要对页中的行进行遍历吗?当然不是,这个时候主键的作用就显现了,我们知道每页Page Directory中的槽是按照主键的顺序存放的,对于某页中的某条具体记录时通过对Page Directory进行二分查找找到的。

InnoDB中页的页目录(Page Directory)记录的槽是一个稀疏目录,二叉查找的结果只是一个粗略的结果,InnoDB必须通过record header(行的一部分)中的next_record来继续查找目标记录。next_record代表下一个记录的偏移量,即当前记录的位置加上偏移量就是下条记录的起始位置,InnoDB在页内部是通过一种链表的结构来串联各个行记录的。

页内部的结构和B+树的结构很类似(树+链表),只是页内部结构的树是二叉的而已。

 

B+树索引的叶子节点是按大小有序的双向链表,且叶子节点中的行记录也是有序的双向链表,对于范围查找特别快。比如查找最后注册的10位用户,由于B+树是双向链表的,用户可以快速找到最后一个页,并取出页中的最后10条记录。

 

索引的生成:

InnoDB支持B+树索引,全文索引,哈希索引,B+树索引就是传统意义上的索引,其构造类似于二叉树,根据键值(KEY VALUE)快速找到数据。(B+树不能找到一个给定键值的具体行,能找到的只是被查找数据行所在的页,然后数据库通过把页读入到内存进行查找最后找到目标行)

B+树索引分为聚集索引和辅助索引:无论哪一种都是B+树:高度平衡,叶子节点存放所有数据,区别是叶子节点存放的是否是一整行信息。

B+树索引的本质是B+数在数据库中的实现,B+树索引在数据库中特点是高扇出性,因此索引一般2~4层。也就是说查找某条记录时最多需要2~4次IO。

B+树中的B代表平衡balance,因为B+树是从平衡二叉树演化而来的。但B+树不是二叉树。

聚集索引

innoDB存储引擎表是索引组织表(跟索引没关系),即表中数据按照主键顺序存放。而聚集索引就是按照每张表的主键生成一颗B+树(因此也叫主键索引),同时所有叶子节点合起来就是整张表的行记录数据,也将聚集索引的叶子节点称为数据页。这个特性决定了:索引组织表的数据便是聚集索引的一部分。聚集索引同B+树数据结构一样,数据页之间通过双向链表来连接。(创建聚集索引的时机是?创建空表时会创建聚集索引吗?)

由于每张表的主键只能有一个,因此每张表只能拥有一个聚集索引。

多数情况下,优化器倾向于使用聚集索引查找数据,因为聚集索引(对应的B+树)的叶子节点上可以直接找到数据。

聚集索引在物理上并不是顺序存储的,不然维护成本会非常高。(这句话是针对叶子节点/页和页中的行记录的,但想必树的非叶子节点也不会是顺序存储的,因为顺序存储存树结构同样在删除或插入时难以维护)

辅助索引

也叫非聚集索引,叶子节点不包含行记录的全部数据(辅助索引的叶子节点包含索引列的值和主键的值)。叶子节点的索引行中包含一个书签来指示行数据的位置。其实该书签就是行数据的聚集索引的键

每张表可以有多个辅助索引,当通过辅助索引查找数据时,innoDB存储引擎会从辅助索引根节点开始找到叶级别的指针获取指向主键索引(聚集索引)的主键,然后再从主键索引根节点开始找到该主键对应的叶子节点(数据页)。

如果一个辅助索引树和主键索引树的高度都是3,查找数据时共需要6次逻辑IO以得到最终的一个数据页。

联合索引:

联合索引的结构与电话簿类似,人名由姓和名构成,电话簿首先按姓氏对进行排序,然后按名字对有相同姓氏的人进行排序。如果您知道姓,电话簿将非常有用;如果您知道姓和名,电话簿则更为有用,但如果您只知道名不姓,电话簿将没有用处。(查询条件只要含有索引中最左边的列即可,顺序无所谓。不含最左边一定不走索引。)

覆盖索引:

即从辅助索引中的叶子节点中就可以查到要查询的记录,不需要查询聚集索引中的记录。

 

 

前缀索引:

有时候需要索引很长的列,这会让索引变得大且慢,有时候模拟哈希索引还不够,可以索引开始的部分字符,但这样也会降低索引的选择性(有多少不重复的列值.选择性高的索引查找时可以过滤更多的行)。对于BLOB,TEXT,或很长的VARCHAR,必须使用前缀索引,mysql不允许索引这些列的完整长度。为了避免过度降低索引的选择性,可以使用LEFT(字段名,N) 观察查询结果,详见高性能mysql

选择性的大小称为基数,除了基于前缀考虑基数外,有时候也需要考虑查询的具体的值和值的分布性。

 

 

 

数据库视图:

对于复杂的查询事件,每次查询都需要编写MySQL代码效率低下。为了解决这个问题,数据库提供了视图(view)功能。

视图是从一个或多个表(产生视图的表叫基表)或视图中导出的虚表,即视图所对应的数据不进行实际存储。 通过视图看到的数据存放在基表中。

如果你改动了基本表,如果你的视图来源于这个基本表,那视图给你呈现的结果也会随之发生变化。

视图中不能创建索引,但视图可以基于索引生成。
  创建视图
  CREATE VIEW 视图名(列1,列2...) AS SELECT (列1,列2...) FROM ...;

  使用视图
  当成表使用就好

  修改视图
  CREATE OR REPLACE VIEW 视图名 AS SELECT [...] FROM [...];

  查看数据库已有视图
  >SHOW TABLES [like...];(可以使用模糊查找)

show table status where comment='view'

select * from information_schema.tables where table_schema='inner_hotels_ub' and table_type='view';

  查看视图详情
  DESC 视图名或者SHOW FIELDS FROM 视图名

  视图条件限制
  [WITH CHECK OPTION] 

视图可以物化(将视图看到的数据存起来)

物化视图 [1]  (Materialized View)在9i以前的版本叫做快照(SNAPSHOT),从9i开始改名叫做物化视图。它是用于预先计算并保存表连接或聚集等耗时较多的操作的结果,这样,在执行查询时,就可以避免进行这些耗时的操作,从而快速的得到结果。物化视图有很多方面和索引很相似:使用物化视图的目的是为了提高查询性能;物化视图对应用透明,增加和删除物化视图不会影响应用程序中SQL 语句的正确性和有效性;物化视图需要占用存储空间;当基表发生变化时,物化视图也应当刷新。

其中物化视图有三种:聚集物化视图、包含连接物化视图、嵌套物化视图。但三种物化视图的快速刷新的限制条件有很大区别,而其他方面则区别不大。

物化视图和视图类似,反映的是某个查询的结果,但是和视图仅保存SQL定义不同,物化视图本身会存储数据,因此是物化了的视图。

 

数据变更监视:

定时读取mysql的二进制日志来监听mysql数据库数据的变更。

 

explain结果解释:

 id

 SQL执行的顺序的标识,SQL从大到小的执行

1. id相同时,执行顺序由上至下

2. 如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行

3.id如果相同,可以认为是一组,从上往下顺序执行;在所有组中,id值越大,优先级越高,越先执

各项内容含义说明:
A:simple:表示不需要union操作或者不包含子查询的简单select查询。简单SELECT,不使用UNION或子查询等。
B:primary:一个需要union操作或者含有子查询的select,位于最外层的单位查询的select_type即为primary。且只有一个。
C:union:union连接的select查询,除了第一个表外,第二个及以后的表select_type都是union。
D:dependent union:与union一样,出现在union 或union all语句中,但是这个查询要受到外部查询的影响
E:union result:包含union的结果集,在union和union all语句中,因为它不需要参与查询,所以id字段为null
F:subquery:除了from字句中包含的子查询外,其他地方出现的子查询都可能是subquery
G:dependent subquery:与dependent union类似,表示这个subquery的查询要受到外部表查询的影响
H:derived:from字句中出现的子查询。
I:materialized:被物化的子查询
J:UNCACHEABLE SUBQUERY:对于外层的主表,子查询不可被物化,每次都需要计算(耗时操作)
K:UNCACHEABLE UNION:UNION操作中,内层的不可被物化的子查询(类似于UNCACHEABLE SUBQUERY)

 

table

显示的查询表名,如果查询使用了别名,那么这里显示的是别名,如果不涉及对数据表的操作,那么这显示为null,如果显示为尖括号括起来的<derived N>就表示这个是临时表,后边的N就是执行计划中的id,表示结果来自于这个查询产生。如果是尖括号括起来的<union M,N>,与<derived N>类似,也是一个临时表,表示这个结果来自于union查询的id为M,N的结果集。如果是尖括号括起来的<subquery N>,这个表示子查询结果被物化,之后子查询结果可以被复用(数字是几就表示第几步执行后的结果,等同于第一列的id)。

type

表示MySQL在表中找到所需行的方式,又称“访问类型”。

常用的类型有: ALL, index,  range, ref, eq_ref, const, system, NULL(从左到右,性能从差到好)

ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行

index: Full Index Scan,index与ALL区别为index类型只遍历索引树

range:只检索给定范围的行,使用一个索引来选择行

ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值

eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件

const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用system

NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。

possible_keys

指出MySQL能使用哪个索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用

该列完全独立于EXPLAIN输出所示的表的次序。这意味着在possible_keys中的某些键实际上不能按生成的表次序使用。
如果该列是NULL,则没有相关的索引。在这种情况下,可以通过检查WHERE子句看是否它引用某些列或适合索引的列来提高你的查询性能。如果是这样,创造一个适当的索引并且再次用EXPLAIN检查查询

Key

key列显示MySQL实际决定使用的键(索引)

如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

key_len

表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度(key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的)

不损失精确性的情况下,长度越短越好 

ref

表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值

rows

 表示MySQL根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数

Extra

该列包含MySQL解决查询的详细信息,有以下几种情况:

Using where: 列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候,表示mysql服务器将在存储引擎检索行后再进行过滤
Using temporary:表示MySQL需要使用临时表来存储结果集,常见于排序和分组查询
Using filesort:MySQL中无法利用索引完成的排序操作称为“文件排序”
Using join  buffer:
改值强调了在获取连接条件时没有使用索引,并且需要连接缓冲区来存储中间结果。如果出现了这个值,那应该注意,根据查询的具体情况可能需要添加索引来改进能。
Impossible where:这个值强调了where语句会导致没有符合条件的行。
Select tables optimized away:这个值意味着仅通过使用索引,优化器可能仅从聚合函数结果中返回一行

 

视图和存储过程像正逆向。

存储引擎区别:http://www.cnblogs.com/zhengah/p/4664324.html

InnoDB支持事务

 

不宜创建索引的情形

1.对经常插入,修改,删除的数据表 不宜创建过多的索引。

2.对数据量比较小的表不必需创建索引

B+树索引的优势体现在

树查找,范围查找

 

 

count()

1.统计列值的数量(有具体列名或列名表达式)

2.统计所有行数(*时,mysql知道某列不可能为null时(如定义字段不能为null)会转化为*)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值