数据库存储&数据加载

数据库存储结构

记录是按照行来存储的,但是数据库的读取并不以行为单位。在数据库中,不论读一行,还是读多行,都是将这些行所在的页进行加载。也就是说,数据库管理存储空间的基本单位是页(Page)。同时在数据库中,还存在这区(Extent),段(Segment)和表空间(Tablespace)。其关系如下:


image.png
  • 区:比页大一级的存储结构,在InnoDB存储引擎中,一个区会分配64个连续的页。因为InnoDB中页大小默认是16KB,所以一个区的大小是1MB。
  • 段:由一个区或多个区组成,区在文件系统中是一个连续分配的空间,不过在段中不要求区与区之间相邻。段是数据库中的分配单位,不同类型的数据库对象会以不同的段形式存在。当我们创建数据库的时候,就会相应创建对应的段,比如创建一张表时会创建一个表段,创建一个索引时会创建一个索引段。
  • 表空间:是一个逻辑容器,表空间存储的对象是段,在一个表空间中可以有一个或多个段,但是一个段只能属于一个表空间。数据库由一个或多个表空间组成的,表空间从管理上可以划分为系统表空间,用户表空间,撤销表空间,临时表空间。
    InnoDB中存在两种表空间:共享表空间和独立表空间。共享表空间意味着多张表公用一个表空间。独立表空间意味着每张表有一个独立的表空间,也就是数据和索引信息会保存在自己的表空间,可以在不同的数据库之间进行迁移。
  • 页:数据库I/O操作的最小单位是页,与数据库中相关的内容都会存储在页结构中。页包括7个部分,分为3类:
    (1)文件通用部分:文件头,文件尾。通过文件头和文件尾校验的方式来确保页的传输是完整的。文件头中存储两个指针,分别指向上一个数据页和下一个数据页。文件尾的校验方式采用来Hash算法进行校验,通过文件尾的校验和文件头的校验对比;
    (2)记录部分:最小和最大记录,用户记录,空闲空间;
    (3)索引部分:页目录,起到了记录的索引作用。在页中,记录是以单项链表的形式进行存储。在页目录中提供二分查找方法。
B+树索引

MySQL的InnoDB存储引擎采用B+树作为索引:


image.png
  • 每个节点都是一个页,每次新建节点的时候,就会申请一个页空间;
  • 叶子节点,B+树最底层的节点,节点的高度为0,存储行记录;
  • 非叶子节点,节点的高度大于0,存储索引键和页面指针,并不存储记录本身;

如果通过 B+ 树的索引查询行记录,首先是从 B+ 树的根开始,逐层检索,直到找到叶子节点,也就是找到对应的数据页为止,将数据页加载到内存中,页目录中的槽(slot)采用二分查找的方式先找到一个粗略的记录分组,然后再在分组中通过链表遍历的方式查找记录。

数据库缓冲池

磁盘 I/O 需要消耗的时间很多,而在内存中进行操作,效率则会高很多,为了能让数据表或者索引中的数据随时被我们所用,DBMS 会申请占用内存来作为数据缓冲池。
缓冲池管理器会尽量将经常使用的数据保存起来,在数据库进行页面读操作的时候,首先会判断该页面是否在缓冲池中,如果存在就直接读取,如果不存在,就会通过内存或磁盘将页面存放到缓冲池中再进行读取。
当我们对数据库中的记录进行修改的时候,首先会修改缓冲池中页里面的记录信息,然后数据库会以一定的频率刷新到磁盘上。注意并不是每次发生更新操作,都会立刻进行磁盘回写。缓冲池会采用一种叫做 checkpoint 的机制将数据回写到磁盘上,这样做的好处就是提升了数据库的整体性能。
当缓冲池不够用时,需要释放掉一些不常用的页,就可以采用强行采用 checkpoint 的方式,将不常用的脏页回写到磁盘上,然后再从缓冲池中将这些页释放掉。这里脏页(dirty page)指的是缓冲池中被修改过的页,与磁盘上的数据页不一致。

缓冲池操作
  1. 查看缓冲池大小
    • MySQL MyISAM 存储引擎,它只缓存索引,不缓存数据,对应的键缓存参数为 key_buffer_size
    • InnoDB 存储引擎,可以通过查看 innodb_buffer_pool_size 变量来查看缓冲池的大小
    mysql > show variables like 'innodb_buffer_pool_size'
    
  2. 修改缓冲池大小
    //134217728=128M
    mysql > set global innodb_buffer_pool_size = 134217728;
    
  3. 开启多个缓冲池
    在 InnoDB 存储引擎中,可以同时开启多个缓冲池。
    • 首先需要将innodb_buffer_pool_size参数设置为大于等于 1GB,这时innodb_buffer_pool_instances才会大于 1。在 MySQL 的配置文件中对innodb_buffer_pool_size进行设置,大于等于 1GB。
    • 然后再针对innodb_buffer_pool_instances参数进行修改。
页面加载方式

如果缓冲池中没有该页数据,那么缓冲池有3种读取数据的方式:

  1. 内存读取:如果数据存在与内存,直接从内存中读取,效率高;
  2. 随机读取:如果数据没有在内存中,需要从磁盘上对页进行查找,将页从磁盘服务器缓冲区传输到数据库缓冲区中,效率低;
  3. 顺序读取:批量读取方式,请求的数据在磁盘上通常都是相邻的,顺序读取可以批量读取页面,这样一次性加载到缓冲池中就不需要再对其他页面单独进行I/O操作了。采用批量读取的方式,即使是从磁盘上进行读取,效率也比从内存中只单独读取一个页的效率高;

查询优化器的成本,统计刚才执行的SQL语句需要加载多少个页面:

 mysql > show status like 'last_query_cost';
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容