我们大多数人可能会同意使用数据库索引是好的。太多的索引和性能实际上会降低。
作为一般规则,哪些字段应该被索引?
哪些字段不应该被索引?
在索引过多和不足之间取得平衡以实现性能改进而不是降级时,使用索引的规则是什么?
gbn*_*gbn 24
我认为“索引过多”规则有点误导。
鉴于平均数据库大约有 98% 的读取(或更高)读取需要优化。例如,如果存在唯一索引,则 INSERT 是读取。或更新的 WHERE。我曾经读到,即使是写入密集型的数据库,仍然有 85% 的读取。
你所拥有的是低质量的索引。例子:
cold, cole和cold, cole, colf)请注意,即使在 OLTP 系统中,索引也比实际数据大几倍是很常见的。
一般来说,我会从
然后我会看:
话虽如此,在看到事情如何发展(100 亿行之后)来调整系统后,我已经打破了某些系统的这些规则。但我永远不会考虑不索引,除非我能证明我为什么这样做。
我想在这里补充一点,不同的数据库需要不同的策略。例如,让我们比较 MySQL w/InnoDB 和 PostgreSQL。
数据库
InnoDB 表基本上是主键的 b 树索引,它被扩展为包括索引条目中的行信息。不支持物理顺序扫描,所有扫描都按逻辑顺序进行。这意味着两件事:
Innodb 中的顺序扫描会产生大量随机磁盘 I/O,并且
无论是否使用二级索引,都必须遍历主键索引。
在此模型中,主键查找比任何其他方法都快。
在这种情况下,在多页表中索引足够多的字段非常重要。典型的规则是索引您要过滤的所有内容。
PostgreSQL
PostgreSQL 使用堆文件,每个文件一个表(有些表可能是许多文件),其中元组从该堆的可用空间中分配。支持物理订单扫描。要使逻辑顺序扫描起作用,必须添加索引。
PostgreSQL 中的主键基本上是唯一索引的子集,其中没有值可能为 NULL。UNIQUE 约束是使用隐式索引完成的,并且支持其他几种索引类型,并在索引中进行不同的操作。
这意味着:
主键查找,假设一个相当大的表需要命中一个索引文件和一个表文件。这比 MySQL 的方法要慢得多,后者只需要遍历索引并且行包含在索引中。
物理顺序扫描的性能要好得多,减少了要处理大量行的随机磁盘 I/O。
二级索引扫描的性能比 MySQL 更好,因为只需要遍历一个索引即可到达表的物理部分。
在这个模型中,索引通常是必要的,但规划者在使用索引时有更多的自由,不使用索引的影响通常不那么严重。这些表更普遍地优化(而不是专门用于 pkey 查找),因此需要的索引更少。
TL; 博士
了解您的 RDBMS。