1
ryd994 2021-04-19 04:32:39 +08:00 via Android
1. 所以要控制索引大小,保证索引能在内存里。
2. 数据库性能确实要看硬盘 iops |
2
LeeReamond OP @ryd994 说是这么说,但是实际上索引大小都是跟业务相关的吧,能加的都加,要不然就变成 ALL 搜索了。。
|
3
Mithril 2021-04-19 07:41:18 +08:00
1. 持久化管理本身就是数据库管理系统的一大功能。
2. 如果纯粹是从硬盘读取的话是有可能的,一般数据库会为了避免这样预先分配好一定大小的空间,而且也允许用户自己控制。比如直接分配个几百 G,或者每次按照一定大小增长。这样的话在一个空的硬盘上空间都会是连续的。 3. 是的。 |
4
qaweqa 2021-04-19 08:08:17 +08:00
有些实现会尽可能让页都按顺序存储。(也就是数据库参与管理)
|
5
dingwen07 2021-04-19 09:11:08 +08:00 via iPhone
第一个问题看情况,Oracle 支持 RAW 的块设备,这个时候就由 Oracle 来管理了。
似乎固态硬盘全是由主控管理的? |
6
shakoon 2021-04-19 09:49:55 +08:00 1
我觉得楼主这个问题涉及到了应用程序层面、操作系统层面、硬件设备固件层面。每一个层面都有自己的优化算法可以对读写方式进行专门指定,但是一般来说,应用程序和操作系统都是没有办法改变硬件固件已经设定好的读写方式,但是如果觉得操作系统对硬件的调度算法对该应用不够最优,应用程序也是有可能直接操作读写硬件的,也就是跳过大部分操作系统常规的硬件调用 api 。最常见的场景就是,各种数据恢复软件、分区软件。
如 5 楼所言,常见数据库 oracle 、db2 较早已经提供了以 raw 方式读写磁盘以提供更优化的 io 性能。但这种模式下,应用程序对磁盘是完全独占的,即该分区将完全有应用所调度,其他程序是不能进行任何访问和操作的。 3 楼说的预先分配表空间的方式,对数据仓库类大量 insert 和 select 的应用来说效率很高,但是一旦涉及 update 和 delete,数据依然会产生物理上的不连续,当然相比完全由 os 管理还是要好得多。 固态硬盘有不少不会有碎片,只是由于其读写速度远高于磁盘的机械运动,碎片带来的影响在和磁盘相比上已经是若干数量级的区别了,所以一般都给忽略掉了。较大型的数据中心现在已经普遍在应用 ssd 阵列的存储设备了,和传统存储相比确实快了几倍(但没有到几个数量级的差别)。但是考虑到综合成本的问题,长期存储的数据主要还是在磁盘存储上,重要应用和需要经常读写的数据才放 ssd 上,毕竟二者价钱差异还是很大的。 |
7
cpstar 2021-04-19 10:12:02 +08:00
LZ 没有实操过吧,使用文件形式 MyISAM 存储的 mysql,过一段时间时间,表就得 optimize 一下清理碎片,INODB 会好一些。
这个事情涉及到 DBMS 的设计规则,最上层的表征当然是一个 SELECT 的效率,但是其中涉及到数据模型(表)的存储设计,操作系统的文件机制(磁盘分区格式)以及操作系统层以下的磁盘阵列机制(再往下就是单盘内部的缓存和存储组织形式)。 诚如楼上两回复所示,操作系统文件管理机制在其中,并不是最关键的,普遍 DBMS 会向 OS 申请一个较大的空间,然后文件系统决定是连续存储还是分片存储,所以为了进一步压榨,干脆把整盘独占给 DBMS——这个整盘并不是物理上的整盘而是经过了软硬件机制整合过的整块存储区。那么透过其本质,实际上就是 DBMS 在做一个文件存储系统,再进一步说,如果这台服务器事实上只处理 DBMS,那么是不是可以把 DBMS 和 OS 合并在一起,所以 Oracle 有数据库一体机,OS 经过调教,虽然还是 unix-like,但已经无关紧要了。 |
8
ch2 2021-04-19 10:22:36 +08:00 via iPhone
SSD 并不一定比 HDD 快
|
9
wakzz 2021-04-19 13:11:16 +08:00
1. MySQL 的 innodb 是通过预先分配磁盘空间的形式来减少碎片化问题,默认是每次申请 1M 大小的连续磁盘;
2. 每 1M 的连续读操作才遇到一次物理不连续,导致的性能消耗影响相对较小,甚至可以忽略; 3. 事实上数据库都有一个缓存层来缓存物理文件数据,性能正常的 innodb 引擎的缓存命中率要不低于 99%,当发生大量缓存命中失败导致大量磁盘读取时,更应该考虑如何提高缓存命中率,而不是物理磁盘碎片的问题; |
10
chihiro2014 2021-04-19 13:17:23 +08:00
系统本身会有一个 rowid 的隐藏字段,我记得
数据库会尽量保证将数据连续保存,因为是机械硬盘,所以数据库设计的时候需要考虑降低磁盘臂旋转的问题,让每次读取 /写入数据时,能处理更多数据。 SSD 确实就没这问题。但将数据尽量放一起,性能确实会提高。遇上碎片化问题,PostgreSQL 是有个 vaccum 功能,可以清理,重新整理数据。 |
11
LeeReamond OP |
12
XiaoxiaoPu 2021-04-19 13:35:11 +08:00
@LeeReamond 不挂载文件系统,直接读写块设备(例如 /dev/sda)就可以做到了。极端点,连内核驱动都可以绕过,比如 SPDK
|
13
dblpx 2021-04-19 13:42:46 +08:00
每次申请 1M 的连续空间吗,innodb 每一页是 16k,B+树每个节点也是 16k 、16k 从磁盘读,我还以为申请空间也是每次 16k😨
|
14
dblpx 2021-04-19 13:43:51 +08:00
@wakzz 每次申请 1M 的连续空间吗,innodb 每一页是 16k,B+树每个节点也是 16k 、16k 从磁盘读,我还以为申请空间也是每次 16k😨
|
15
wakzz 2021-04-19 13:44:00 +08:00 1
@LeeReamond mysql 的 innodb 的缓存层是直接缓存的磁盘文件,不是对 sql 结果的缓存,而是对物理文件分片(每个分片默认 16K)的缓存。
比如一个查询涉及到多条行记录,innodb 会先去索引树找到对应记录的具体物理文件分片位置,然后到缓存层尝试命中这几条记录所在的物理文件分片。缓存命中不到后再去物理磁盘上读取文件分片数据,然后再在内存中聚合查询处理操作。 |