SQL必知必会(二)-优化篇

SQL优化篇

一,数据库优化篇

1.优化从那些方面

1.1数据库选择层面,比如传统数据库,键值型数据库,文档型数据库,搜索引擎库
            1.2表设计,根据范式或反范式设计合理的库表,表字段根据实际要求设置类型
1.3逻辑优化,sql语句方面优化,尽量不走全表扫描
1.4物理优化,建立索引
1.5添加中间件,比如redis,memcached做为缓存服务器
1.6 读写分离,主从备份
1.7分库分表

2.范式与反范式、

1NF:原子性,字段不可分割
2NF:  非主属性完全依赖主属性
3NF:不能存在间接依赖或传递依赖关系
反范式:有时候发现使用范式并不合理,为了数据库性能退化为第二范式,并改进内容

二,索引

1.索引概览

1.有哪些索引
功能逻辑:主键索引,联合索引,唯一索引,全文索引
物理实现: 聚集索引,非聚集索引
2.索引的使用规则

2. 索引原理

1.平衡二叉树

二叉树的基础上限制:左右子树高度差不超过1

2.B-tree树数据结构

1个m阶的B树:
节点内关键字(元素)数k:(2/m向下取整<=k<m)
每个节点最多m个子节点
除根节点和叶子节点,(中间节点)至少m/2向上取整个子节点
所有子节点在同一层
每个节点内有k个关键字(元素),有k+1个指针,有k行数据	

3.B+tree数据结构

B+树在满足B树的基础上,非叶子节点不存储数据,而是主键或索引元素值
叶子节点存储数据行或聚集索引的key
叶子节点之间用双向指针链接

4.B-tree与B+tree树区别,性能比较

B-tree应为数据在节点中,所以适合等值查询
B+tree数据在叶子节点且用双向指针链接,所以适合范围查询
同等空间内B+tree存储数据更多
同样总量数据B-tree深度更深,查询效率更低

5.Innobo数据引擎的数据存储

采用B+Tree结构存储
innodb引擎数据在物理上是按主键顺序存放
页内数据不是完全有序,所以用单向指针链接数据。
当前页做根节点而不是新建一个页做根节点:如果是重新创建根结点,那根结点存储的物理地址可能经常会变,不利于查找。
并且在innodb中根结点是会预读到内存中的,所以结点的物理地址固定会比较好!
减少数据分裂次数:每次新增数据,都是将一个页写满,然后新创建一个页继续写	

6.回表

1.innobo数据库非聚集索引叶子节点存储聚集索引的key,拿着key取聚集索引查数据,
这一现象被称为回表
2.myisam叶子节点存放的是数据地址,非聚集索引查数据时不需要回表

7.避免回表

加大联合索引的宽度(多个字段做联合索引,但这会降低DDL效率)
通过宽索引将 SELECT 中需要用到的列(主键列可以除外)都设置在宽索引中,这样就避免了回表扫描的情况,从而提升 SQL 查询效率

8.数据读取时局部性原理

操作系统从磁盘读取数据到内存是以磁盘块(block)为基本单位的,
位于同一个磁盘块中的数据会被一次性读取出来,而不是需要什么取什么。

9.mysql的innobo为什么主键自增

每次新增数据,都是将一个页写满,然后新创建一个页继续写,这里其实是有个隐含条件的,
那就是主键自增!主键自增写入时新插入的数据不会影响到原有页,插入效率高!且页的利用率高!但是如果主键是无序的或者随机的,
那每次的插入可能会导致原有页频繁的分裂,影响插入效率!降低页的利用率!这也是为什么在innodb中建议设置主键自增的原因!

10.innobo的聚集索引,非聚集索引 ,怎样进行数据查找的

非聚集索引:采用B+Tree 叶子节点存放聚集索引的key
聚集索引:采用B+Tree一个表中只有一个聚集索引
查找数据:
1、找到数据所在的页。这个查找过程就跟前面说到的B+Tree的搜索过程是一样的,从根结点开始查找一直到叶子结点。
2、在页内找具体的数据。读取第1步找到的叶子结点数据到内存中,然后通过分块查找的方法找到具体的数据。

11.myisam的索引

1、主键索引树的叶子结点的数据区域没有存放实际的数据,存放的是数据记录的地址。
2、数据的存储不是按主键顺序存放的,按写入的顺序存放。
3、非聚集索引和聚集索引结构相似,叶子节点都存放数据地址

12.联合索引最左匹配原则

一个联合索引(x,y,z),查询条件y,z,x
1.SQL优化器会对sql进行重写,仍会走联合索引
2.where条件未非等值(>,<,<>,between等)是,之后的查询条件不会走索引

13.数据库中的存储结构是怎样的

在这里插入图片描述

在这里插入图片描述

在数据库中,不论读一行,还是读多行,都是将这些行所在的页进行加载。也就是说,数据库管理存储空间的基本单位是页
1.一个页中可以存储多个行记录(Row),同时在数据库中,还存在着区(Extent)、段(Segment)和表空间(Tablespace)。

2.区(Extent)是比页大一级的存储结构,在 InnoDB 存储引擎中,一个区会分配 64 个连续的页。因为 InnoDB 中的页大小默认是 16KB,所以一个区的大小是 64*16KB=1MB。

3.段(Segment)由一个或多个区组成,区在文件系统是一个连续分配的空间(在 InnoDB 中是连续的 64 个页),不过在段中不要求区与区之间是相邻的。段是数据库中的分配单位,不同类型的数据库对象以不同的段形式存在。当我们创建数据表、索引的时候,就会相应创建对应的段,比如创建一张表时会创建一个表段,创建一个索引时会创建一个索引段。

4.表空间(Tablespace)是一个逻辑容器,表空间存储的对象是段,在一个表空间中可以有一个或多个段,但是一个段只能属于一个表空间。数据库由一个或多个表空间组成,表空间从管理上可以划分为系统表空间、用户表空间、撤销表空间、临时表空间等。

5.在 InnoDB 中存在两种表空间的类型:共享表空间和独立表空间。如果是共享表空间就意味着多张表共用一个表空间。如果是独立表空间,就意味着每张表有一个独立的表空间,也就是数据和索引信息都会保存在自己的表空间中。独立的表空间可以在不同的数据库之间进行迁移。

三.hash索引

hash索引与B+树的区别

hash索引与B+Tree的区别 我们之前讲到过 B+ 树索引的结构,Hash 索引结构和 B+ 树的不同,因此在索引使用上也会有差别。
1.Hash 索引不能进行范围查询,而 B+ 树可以。这是因为 Hash 索引指向的数据是无序的,而 B+ 树的叶子节点是个有序的链表。
2.Hash 索引不支持联合索引的最左侧原则(即联合索引的部分索引无法使用),而 B+ 树可以。对于联合索引来说,Hash 索引在计算 Hash 值的时候是将索引键合并后再一起计算 Hash 值,所以不会针对每个索引单独计算 Hash 值。因此如果用到联合索引的一个或者几个索引时,联合索引无法被利用。
3.Hash 索引不支持 ORDER BY 排序,因为 Hash 索引指向的数据是无序的,因此无法起到排序优化的作用,而 B+ 树索引数据是有序的,可以起到对该字段 ORDER BY 排序优化的作用。同理,我们也无法用 Hash 索引进行模糊查询,而 B+ 树使用 LIKE 进行模糊查询的时候, LIKE 后面前模糊查询(比如 % 开头)的话就可以起到优化作用。对于等值查询来说,通常 Hash 索引的效率更高,

2.自适应hash索引的原理

hash索引只保存热数据,自适应hash也是放到缓冲池中,它直接存储的是热点数据页,是索引中的索引
自适应 Hash 采用 Hash 函数映射到一个 Hash 表中Hash 表是数组 + 链表的形式。通过 Hash 函数可以计算索引键值所对应的bucket(桶)的位置,如果产生 Hash 冲突,就需要遍历链表来解决

四,三星索引

1.什么是三星索引

三星索引具体指的是:

  1. 在 WHERE 条件语句中,找到所有等值谓词中的条件列,将它们作为索引片中的开始列;
  2. 将 GROUP BY 和 ORDER BY 中的列加入到索引中;
  3. 将 SELECT 字段中剩余的列加入到索引片中。

猜你喜欢

转载自blog.csdn.net/qq_41201565/article/details/105847985