数据库存储&数据加载

2019-11-08  本文已影响0人  LittleJessy
数据库存储结构

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


image.png
B+树索引

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


image.png

如果通过 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';
上一篇 下一篇

猜你喜欢

热点阅读