数据库索引是不是与列数据占用相同数量的磁盘空间?
Posted
技术标签:
【中文标题】数据库索引是不是与列数据占用相同数量的磁盘空间?【英文标题】:Do DB indexes take same amount of disc space as column data?数据库索引是否与列数据占用相同数量的磁盘空间? 【发布时间】:2011-01-24 01:03:44 【问题描述】:如果我有一个包含数据的表列并在该列上创建索引,该索引会占用与列本身相同的磁盘空间吗?
我很感兴趣,因为我想了解 b 树是否实际上将列数据的副本保存在叶节点中,或者它们是否以某种方式指向它?
很抱歉,如果这是“Java 会取代 XML 吗?”好问题。
更新:
使用单个 GUID 列创建了一个没有索引的表,添加了 1M 行 - 26MB
具有主键(聚集索引)的同一张表 - 25MB(甚至更小!),索引大小 - 176KB
具有唯一键的同一张表(非聚集索引) - 26MB,索引大小 - 27MB
因此,只有非聚集索引占用的空间与数据本身一样多。
所有测量均在 SQL Server 2005 中完成
【问题讨论】:
【参考方案1】:从article 来看,事实上,它至少会占用与列中的数据相同的空间(无论如何,在 PostgreSQL 中)。 这篇文章还提出了一种减少磁盘和内存使用的策略。
检查自己的方法是使用例如derby DB,创建一个包含一百万行和一列的表,检查它的大小,在列上创建一个索引并再次检查它的大小。如果您花 10-15 分钟这样做,请告诉我们结果。 :)
【讨论】:
我认为这取决于索引的行数。例如,如果一个表包含 30 行但只有 2 行是可搜索的,那么这些特定行只需要 2 个 b 树。这就是为什么不索引不会用于查找的行很重要。 @Evan:我不确定我是否遵循...您的意思是“取决于索引的列数”吗? 是的...我说列不是我;) 在这种情况下,当然,默认情况下索引不是“好”:它们是有代价的,无论是在 RAM 和磁盘(索引存储)方面还是在 CPU 周期方面(C- UD 操作需要更新索引)。 没错。因此,如果您有一个像 FIFO 任务队列这样的高吞吐量表,那么对任何列进行索引都会对性能产生负面影响。即使在写入率较低的表(例如持久数据存储)上,它也会节省一些时间/资源来排除您只希望在结果中可见的列。通常,外键几乎总是索引的好主意,因为连接上的每个额外外键查找都会向该查询添加额外的表搜索。联接会很快变得昂贵,这就是许多新的非 SQL 数据架构不允许它们的原因。【参考方案2】:B-Tree 指向表中的行,但 B-Tree 本身仍然占用一些磁盘空间。
一些数据库,有嵌入主索引和数据的特殊表。在 Oracle 中,它被称为 IOT——索引组织表。
常规表中的每一行都可以通过 B-Tree 用来识别行的内部 ID(但它是特定于数据库的)来识别。在 Oracle 中,它被称为 rowid
,看起来像 AAAAECAABAAAAgiAAA
:)
如果我有一个包含数据的表格列,并且 在该列上创建索引,将 索引占用相同数量的磁盘 空间作为列本身?
在基本的 B 树中,节点数与列中的项目数相同。
考虑1,2,3,4
:
1
/
2
\ 3
\ 4
确切的空间还是会有点不同(索引可能有点大,因为它需要存储节点之间的链接,它可能没有完美平衡等等),我猜数据库可以使用优化来压缩部分的指数。但是索引和列数据的数量级应该是一致的。
【讨论】:
它是一种聚集索引吗? 我认为聚集索引存储实际数据,因为聚集索引的排序方式与数据相同。 是的,IOT 类似于聚集索引。表中的行在物理上重新排序。查询数据性能出色,但插入速度较慢。【参考方案3】:我几乎可以肯定它完全依赖于数据库,但通常 – 是的,它们占用了额外的空间。发生这种情况有两个原因:
这样你就可以利用事实 BTREE叶子中的数据被排序;
您获得了查找速度优势,因为 你不必回头寻找 去取必要的东西。
PS 刚刚检查了我们的 mysql 服务器:对于 20GB 的表索引占用 10GB 空间:)
【讨论】:
以上是关于数据库索引是不是与列数据占用相同数量的磁盘空间?的主要内容,如果未能解决你的问题,请参考以下文章