一 , 逻辑分层

  

连接层:连接与线程处理,这一层并不是MySQL独有,一般的基于C/S架构的都有类似组件,比如连接处理、授权认证、安全等。

服务层:包括缓存查询、解析器、优化器,这一部分是MySQL核心功能,包括解析、优化SQL语句,查询缓存目录,内置函数(日期、时间、加密等函数)的实现。

引擎层:负责数据存储,存储引擎的不同,存储方式、数据格式、提取方式等都不相同,这一部分也是很大影响数据存储与提取的性能的;对存储层的抽象。

存储层:存储数据,文件系统。

二 , 存储引擎

查看数据库支持的存储引擎:show engines;

如果要想查看数据库默认使用哪个引擎,可以通过使用命令: show variables like '%storage_engine%';

指定数据库对象的引擎:
create table tb(
id int(4) auto_increment ,
name varchar(5),
dept varchar(5) ,
primary key(id)
)ENGINE=MyISAM AUTO_INCREMENT=1
DEFAULT CHARSET=utf8 ;

查看建表语句:show create table default_table;

InnoDB,MyISAM的主要区别:

InnoDB:在MySQL5.5开始作为默认的存储引擎,支持事务,行级锁,适合高并发场景,XA协议支持分布式事务。

MyISAM:不支持事务,性能优先,表级锁,不适合高并发场景。

三, sql优化

  3.1.1  mysql 内部实现索引原理(B+Tree)  参考(https://blog.csdn.net/chuixue24/article/details/80027689)

    3.1.1.1 ,  二叉树

      

     3.1.1.2 ,  B-Tree

          

        B-Tree中的每个节点根据实际情况可以包含大量的关键字信息和分支,如下图所示为一个3阶的B-Tree: 
        

每个节点占用一个盘块的磁盘空间,一个节点上有两个升序排序的关键字和三个指向子树根节点的指针,指针存储的是子节点所在磁盘块的地址。两个关键词划分成的三个范围域对应三个指针指向的子树的数据的范围域。以根节点为例,关键字为17和35,P1指针指向的子树的数据范围为小于17,P2指针指向的子树的数据范围为17~35,P3指针指向的子树的数据范围为大于35。

      模拟查找关键字29的过程:

      1. 根据根节点找到磁盘块1,读入内存。【磁盘I/O操作第1次】 
      2. 比较关键字29在区间(17,35),找到磁盘块1的指针P2。
      3. 根据P2指针找到磁盘块3,读入内存。【磁盘I/O操作第2次】
      4. 比较关键字29在区间(26,30),找到磁盘块3的指针P2。
      5. 根据P2指针找到磁盘块8,读入内存。【磁盘I/O操作第3次】
      6. 在磁盘块8中的关键字列表中找到关键字29。

    分析上面过程,发现需要3次磁盘I/O操作,和3次内存查找操作。由于内存中的关键字是一个有序表结构,可以利用二分法查找提高效率。而3次磁盘I/O操作是影响整个B-Tree查找效率的决定因素。

      B-Tree相对于AVLTree缩减了节点个数,使每次磁盘I/O取到内存的数据都发挥了作用,从而提高了查询效率。

     3.1.1.3 ,  B+Tree(查询任意数据的次数是 n)

      B+Tree是在B-Tree基础上的一种优化,使其更适合实现外存储索引结构,InnoDB存储引擎就是用B+Tree实现其索引结构。

从上一节中的B-Tree结构图中可以看到每个节点中不仅包含数据的key值,还有data值。而每一个页的存储空间是有限的,如果data数据较大时将会导致每个节点(即一个页)能存储的key的数量很小,当存储的数据量很大时同样会导致B-Tree的深度较大,增大查询时的磁盘I/O次数,进而影响查询效率。在B+Tree中,所有数据记录节点都是按照键值大小顺序存放在同一层的叶子节点上,而非叶子节点上只存储key值信息,这样可以大大加大每个节点存储的key值数量,降低B+Tree的高度。

B+Tree相对于B-Tree有几点不同:

  1. 非叶子节点只存储键值信息。
  2. 所有叶子节点之间都有一个链指针。
  3. 数据记录都存放在叶子节点中。

将上一节中的B-Tree优化,由于B+Tree的非叶子节点只存储键值信息,假设每个磁盘块能存储4个键值及指针信息,则变成B+Tree后其结构如下图所示: 

通常在B+Tree上有两个头指针,一个指向根节点,另一个指向关键字最小的叶子节点,而且所有叶子节点(即数据节点)之间是一种链式环结构。因此可以对B+Tree进行两种查找运算:一种是对于主键的范围查找和分页查找,另一种是从根节点开始,进行随机查找。

上面都应该知道B+Tree 了吧,所以我们在建立索引时,会生成一个B+Tree  如果我们在只查询索引字段时,sql 语句就直接去B+Tree 查,不会再去数据表中查了,这样提升性能是很重要的。 还有就是对于总是修改的字段不要对他建立索引,因为字段修改了,B+Tree 结构就要重构,这要是会降低性能的。

  3.1.1 索引分类:

      主键索引:是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。一般是在建表的时候某一列定为主键时,就默认的创建了对应的主键索引。

      唯一索引:索引列的值必须唯一,但允许有空值。

      单列索引:对于表中的某一列,添加的索引。

      复合索引:多个列构成的索引(跟书的一级,二级,三级 目录一样),使用时要遵循最佳左前缀特性,如果我们创建了(area, age, salary)的复合索引,那么其实相当于创建了(area,age,salary)、(area,age)、(area)三个索引。

           因此我们在创建复合索引时应该将最常用作限制条件的列放在最左边,依次递减。

   3.2.2 如何正确的建立索引呢?

      3.2.2、创建索引      

         create 索引类型 索引名 on 表(字段)
         单值:  create index dept_index on tb(dept);
         唯一:create unique index name_index on tb(name) ;
         复合索引: create index dept_name_index on tb(dept,name);

        查询索引:
          show index from 表名 ;
          show index from 表名 \G

        删除索引:
          drop index 索引名 on 表名 ;
          drop index name_index on tb ;

      3.2.2、SQL解析顺序
         接下来再走一步,让我们看看一条SQL语句的前世今生。
        首先看一下示例语句
            SELECT DISTINCT  .....   FROM .....  JOIN  .....  ON   .....  WHERE.....   GROUP BY    .....  HAVING  .....   ORDER BY   .....   LIMIT ..... 

            然而它的执行顺序是这样的

            FROM   .....  ON  .....    JOIN  .....   WHERE     ..... GROUP BY     .....  HAVING  .....    SELECT    DISTINCT   .....  ORDER BY   .....  LIMIT   .....

 
      3.2.3 如何建立索引
          

      一般说来,索引应建立在那些将用于JOIN,WHERE判断和ORDERBY排序的字段上。尽量不要对数据库中某个含有大量重复的值的字段建立索引。对于一个ENUM类型的字段来说,出现大量重复值是很有可能的情况.

      3.2.4     使用索引时,有一些技巧:

          1.索引不会包含有NULL的列

           只要列中包含有NULL值,都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此符合索引就是无效的。

         2. 索引要建立在经常进行select操作的字段上。而经常修改的字段,没没必要建立索引了,因为,你建立了索引会生成一个B+树,你修改了该索引的字段后,这个B+树就需要修改,反而对性能不是很好。

         3. 复合索引 : 复合索引,不要跨列或无序使用(最佳左前缀)

         4.like语句操作: 一般情况下不鼓励使用like操作,如果非使用不可,注意正确的使用方式。like ‘%aaa%’不会使用索引,而like ‘aaa%’可以使用索引。

        5. 不要在索引上进行任何操作(计算、函数、类型转换),否则索引失效

        6.不使用NOT IN 、<>、!=操作,但<,<=,=,>,>=,BETWEEN,IN是可以用到索引的

        7.索引要建立在经常进行select操作的字段上。

        这是因为,如果这些列很少用到,那么有无索引并不能明显改变查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。

         8.索引要建立在值比较唯一的字段上。

         9.对于那些定义为text、image和bit数据类型的列不应该增加索引。因为这些列的数据量要么相当大,要么取值很少。

        10.在join操作中(需要从多个数据表提取数据时),mysql只有在主键和外键的数据类型相同时才能使用索引,否则及时建立了索引也不会使用。

三, sql性能问题

    a.分析SQL的执行计划  : explain   ,可以模拟SQL优化器执行SQL语句,从而让开发人员 知道自己编写的SQL状况

    b.MySQL查询优化其会干扰我们的优化(mysql服务层有一个sql优化器),可以对我们写的sql进行优化,这是我们控制不了的。

    查询执行计划:  explain +SQL语句     explain SELECT * from book ;

      

    

id : 编号
select_type :查询类型
table :表
type :索引类型 system>const>eq_ref>ref>range>index>all ,要对type进行优化的前提:有索引 一般能达到range 就行。
possible_keys :预测用到的索引
key :实际使用的索引
key_len :实际使用索引的长度
ref :表之间的引用
rows :通过索引查询到的数据量
Extra :额外的信息 下面是他可能发出的情况

  i). using filesort : 性能消耗大;需要“额外”的一次排序(查询)  。常见于 order by 语句中。 解决:where哪些字段,就order by那些字段2

  ii). using temporary:性能损耗大 ,用到了临时表。一般出现在group by 语句中。 解决: 避免:查询那些列,就根据那些列 group by .

  iii). using index :性能提升; 索引覆盖(覆盖索引)。原因:不读取原文件,只从索引文件中获取数据 (不需要回表查询)
只要使用到的列 全部都在索引中,就是索引覆盖using index

  iii).using where (需要回表查询)。

    假设age是索引列
    但查询语句select age,name from ...where age =...,此语句中必须回原表查Name,因此会显示using where.  解决 吧name  也添加到索引中去。

MySQL(逻辑分层,存储引擎,sql优化,索引优化以及底层实现(B+Tree))的更多相关文章

  1. MySQL最全存储引擎、索引使用及SQL优化的实践

    1 MySQL的体系结构概述 整个MySQL Server由以下组成 :Connection Pool :连接池组件Management Services & Utilities :管理服务和 ...

  2. MySQL:InnoDB存储引擎的B+树索引算法

    很早之前,就从学校的图书馆借了MySQL技术内幕,InnoDB存储引擎这本书,但一直草草阅读,做的笔记也有些凌乱,趁着现在大四了,课程稍微少了一点,整理一下笔记,按照专题写一些,加深一下印象,不枉读了 ...

  3. mysql innodb存储引擎和一些参数优化

    mysql 的innodb存储引擎是事务性引擎,支持acid.innodb支持版本控制和高并发的技术是svcc:需要重点注意:myisam只缓存索引,innodb缓存索引和数据:

  4. Mysql 版本号、存储引擎、索引查询

    [1]Mysql 版本号.存储引擎.索引查询 # 查看数据库版本号 SELECT VERSION(); # 查看数据库支持的引擎(默认即Support == DEFAULT行) SHOW ENGINE ...

  5. MySQL的多存储引擎架构

    支持多种存储引擎是众所周知的MySQL特性,也是MySQL架构的关键优势之一.如果能够理解MySQL Server与存储引擎之间是怎样通过API交互的,将大大有利于理解MySQL的核心基础架构.本文将 ...

  6. MySQL技术内幕读书笔记(一)——Mysql体系结构和存储引擎

    目录 MySQL体系结构和存储引擎 定义数据库和实例 MYSQL体系结构 MYSQL存储引擎 MySQL体系结构和存储引擎 定义数据库和实例 数据库:物理操作系统文件或者其他形式文件类型的结合.在MY ...

  7. MySQL mysql server与存储引擎

    mysql server系统架构 逻辑模块组成: mysql逻辑模块可以分为两层架构,第一层是sql layer主要包括权限判断.sql解析.执行计划优化.query cache的处理等:第二层是存储 ...

  8. MySQL笔记(1)---MySQL体系结构和存储引擎

    1.前言 本系列记录MYSQL数据库的一些结构和实现特点,方便查询. 2.基本概念 数据库:物理操作系统文件或者其他形式文件类型的集合.MySQL中数据库文件可以是frm.MYD.MYI.ibd结尾的 ...

  9. MySql的多存储引擎架构, 默认的引擎InnoDB与 MYISAM的区别(滴滴)

    1.存储引擎是什么? MySQL中的数据用各种不同的技术存储在文件(或者内存)中.这些技术中的每一种技术都使用不同的存储机制.索引技巧.锁定水平并且最终提供广泛的不同的功能和能力.通过选择不同的技术, ...

  10. mysql三-1:存储引擎

    一 什么是存储引擎 mysql中建立的库===>文件夹 库中建立的表===>文件 现实生活中我们用来存储数据的文件有不同的类型,每种文件类型对应各自不同的处理机制:比如处理文本用txt类型 ...

随机推荐

  1. 【1】Git基础

    一.Git概念 1.1.Git定义   Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目.Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发 ...

  2. 【异常】ssh无法登录验证,非root用户ssh本机无法成功

    1 自己搭建的是伪分布式环境,需要以非root用户启动Hadoop集群,之前root已经配置了ssh免密登录,但是自己切换到hdfs用户重新生成了一套ssh key, 但是切换到hdfs始终无法成功登 ...

  3. CAFFE(0):Ubuntu 下安装anaconda2和anaconda3

    这个步骤可以看做是安装caffe可以进行或者不必要的步骤,不过笔者建议安装anaconda2和anaconda3,里面会包含很多的模块,省去caffe学习过程中出现模块不存在的各种错误. 第一步.进入 ...

  4. Istio调用链埋点原理剖析—是否真的“零修改”分享实录(下)

    调用链原理和场景 正如Service Mesh的诞生是为了解决大规模分布式服务访问的治理问题,调用链的出现也是为了对应于大规模的复杂的分布式系统运行中碰到的故障定位定界问题.大量的服务调用.跨进程.跨 ...

  5. 解读Position

    首先Position在字面讲是位置的意思,在HTML中是定位的意思,它有四种属性:分别是static是静态的,也是默认的效果,没有特别的设定,遵循基本的定位规定,不能通过z-index进行层次分级. ...

  6. js获取div基础元素

    1.js获取div元素 clientHeight 获取对象的高度,不计算任何边距.边框.滚动条,但包括该对象的补白. clientLeft 获取 offsetLeft 属性和客户区域的实际左边之间的距 ...

  7. Angular Multiple HTTP Requests with RxJS

    原文:https://coryrylan.com/blog/angular-multiple-http-requests-with-rxjs ----------------------------- ...

  8. python 判断数据类型及释疑

    Python 判断数据类型有type和isinstance 基本区别在于: type():不会认为子类是父类 isinstance():会认为子类是父类类型 class Color(object): ...

  9. Navicat Premium 12连接mysql-8.0.15-winx64 出现2059异常

    错误

  10. springboot整合mybatis-plus逆向工程

    MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发.提高效率而生.官方文档 代码生成器 AutoGenerator 是 ...