MySQL中所有数据以文件的形式保存在磁盘上,而访问磁盘是一个非常耗时的操作。所以数据库和OS提供了缓冲池和内存来提高数据的访问速度。
数据库对数据的访问不是以行为单位的,无论读取一行还是多行,都是将该行所在的页全部记载到内存中,然后在读取对应的数据记录。也可以从另外一个角度理解,读取数据所消耗的时间与行数无关,而是与页数有关。
这种数据访问,让我想起对磁盘数据的访问,每次不会读取一个扇区,而是读取一个或者多个页。同样都是预读取操作。
MySQL中,页的大小一般是16KB,也有可能是其他值,这与存储引擎相关。索引或者行记录是否在缓存池中极大地影响了访问索引或者数据的成本。
数据库等待一个页从磁盘读取到缓冲池需要的时间大约是10ms(巨大的开销)。
等待时间为 3ms、磁盘的实际繁忙时间约为 6ms,最终数据页从磁盘传输到缓冲池的时间为 1ms 左右。
如果在数据库的缓冲池中没有找到相关的数据页,那么回去内存中寻找数据页,时间约是1ms.
从磁盘读取数据并不是都要付出很大的代价,当数据库管理程序一次性从磁盘中顺序读取大量的数据时,读取的速度会异常的快,大概在 40MB/s 左右。
如果一个页面的大小为 4KB,那么 1s 的时间就可以读取 10000 个页,读取一个页面所花费的平均时间就是 0.1ms,相比随机读取的 10ms 已经降低了两个数量级,甚至比内存中读取数据还要快。
数据页面的顺序读取有两个非常重要的优势:
1)同时读取多个界面意味着总时间的消耗会大幅度减少,磁盘的吞吐量可以达到 40MB/s;
2)数据库管理程序会对一些即将使用的界面进行预读,以减少查询请求的等待和响应时间;
2019-07-26
页的概念,这么久了,还是没有建立起来这个关键概念。还是重复的次数和力度不够。
如果有了这个概念,预读取的思维可以用一句俗语概括——搂草打兔子。
这就是访问慢存储的终极奥义。
参考资料:MySQL 索引设计概要