根据我将对其执行的查询来设计表是一种好方法吗?

DT1*_*DT1 1 performance database-design

观看视频,对 dbms 还很陌生。
演讲者解释说,在面向行的数据库中,行是按块读取的。
所以,我的理解是,如果我有字段较少的行,更多的行可以放入一个块中,当我查询表时,它应该进行更少的 IO 操作,从而获得更好的性能..我对吗?

我可以提取规则,我不应该根据它们代表的实体设计表格,而是根据我阅读或更新这些字段的频率吗?

例如:表雇主:

  • ID
  • 名称(常用)
  • 徽章编号(经常使用)
  • 出生日期(很少使用)
  • 出生地(很少使用)

    我应该把桌子一分为二吗?
  • tbl1: ID | 姓名 | 徽章编号
  • tbl2: ID | 出生日期 | 出生地

bba*_*ird 5

在大多数数据库管理系统中,数据存储为页,而不是块。页通常为 4 或 8 KB,具体取决于数据库及其配置方式。

在所有其他条件相同的情况下,较小的行大小将等同于更好地重用缓存页面并减少需要大量行的查询的页面读取 - 因此更少的 I/O 和更快的读取性能。

然而

如果您对表进行垂直分区(如您的示例中所示),整体存储量会略有增加(等于主键长度和行数,加上 b 树),插入性能会稍微变慢,因为您需要维护两个表之间的 PK-FK 关系。

此外,如果您的大多数查询都是针对单条记录查找的,那么您仍将阅读单个页面。页面被缓存的可能性更大,但从现代磁盘中读取 4 或 8 KB 确实不是一项昂贵的操作。

当您需要BirthDate/时,拆分表格将需要 2 页读取(并导航两个 B 树)BirthPlace。同样,对现代硬件来说并不是什么大问题。

我唯一一次对表进行垂直分区是在某些数据仓库情况下,或者如果BirthDate/ 可以BirthPlace为空且不常填充。

其他注意事项

如果徽章编号的大小相对较小(例如,低于 20-30 字节),那么提高性能的最佳做法是删除不需要的ID列并创建主键,BadgeNumber因为:

  1. 您不应该在该列中有重复项
  2. 很可能您将主要查找该列,因此使用BadgeNumber
  • 为您节省一列,使您的表格更紧凑
  • 消除对索引(和相关开销)的需要 BadgeNumber
  • BadgeNumber当表与另一个表具有 PK-FK 关系时,无需加入您的表来获取。

还有其他方法可以减少 I/O 并提高读取性能。大多数商业 DBMS 将支持某种形式的数据压缩。这可以在单个页面上容纳更多行,而不会对表的结构进行任何更改,但代价是在写入/读取数据时压缩/解压缩数据的一些 CPU 开销。CPU 通常是比磁盘更便宜的操作,因此压缩通常是一个净收益。