标题总结了它。
我已经了解到并且一直听说表中的索引可以改进 CRUD 操作。我上周末遇到的一位开发人员告诉我,他不喜欢索引,因为它们很糟糕——是的,“糟糕”并没有说明任何事情,但我们没有时间进一步讨论它(我们在一个聚会上)。
无论如何,也许是因为我缺乏经验,我不知道在 CRUD 操作期间索引会导致麻烦的场景,但也许有一些。我问这个问题是想知道有没有...
标题总结了它。
我已经了解到并且一直听说表中的索引可以改进 CRUD 操作。我上周末遇到的一位开发人员告诉我,他不喜欢索引,因为它们很糟糕——是的,“糟糕”并没有说明任何事情,但我们没有时间进一步讨论它(我们在一个聚会上)。
无论如何,也许是因为我缺乏经验,我不知道在 CRUD 操作期间索引会导致麻烦的场景,但也许有一些。我问这个问题是想知道有没有...
好吧,我认为您有一些混合概念:
索引提高了 READ OPERATIONS(那些 SELECT 的)的性能,同时增加了 INSERT/UPDATE OPERATIONS 的处理时间(因此它们不会改进所有 CRUD 操作,正如您所听到的)。每次插入新行时,都应该更新索引,如果索引太多,则会增加插入时间,有时还会增加更新(如果更新涉及索引的内容。
索引使用空间,如果您有很多行,则会占用大量空间。
系统知道哪个是最好使用的索引不是问题,我认为这不是真正的性能杀手,但你应该寻找冗余索引,因为它们正在使用插入/更新的空间和时间。
为此,您应该知道您的数据库引擎如何与索引一起工作,在 MySQL 中,如果您有一个基于名称、姓氏字段和其他名称的索引,则后者是多余的,因为它包含在第一个中(因为它出现在同一个order, surname only is not included ), 作为冗余索引的示例。
此外,您应该测试您的数据库将如何解释查询以及将使用哪些索引(在 MySQL 中,您可以使用 Explain... 以及您正在测试的查询)
最后,索引是数据库最重要的特性之一,索引本身不会是“坏”的,通常当您忘记添加某些特定索引时会出现问题,而不是索引过多,但它可能会发生。
索引太多确实会导致性能问题。
如果许多索引具有非常相似的统计信息,则优化器可能无法可靠地决定最有用的索引选择。(我在使用几乎每一列都被索引的数据库时了解到这一点。)
在这种情况下,我们通过删除很少使用的列上的索引来显着减少索引的数量。这大大提高了我们查询的性能。
此外,过多的索引导致 (1) 使用更多空间却收效甚微,以及 (2) 消耗更多服务器资源来更新所有多余的索引。
所以,是的,索引确实可以帮助您提高性能,但是您需要合理地创建多少索引。关注对您来说最有用的索引。
附加信息:许多数据库供应商都提供了一些工具来帮助您分析索引的价值和使用情况。例如:
pg_stat_user_indexes
.试图保持数据库中立:
读取、过滤
索引从根本上加快了表上的排序和过滤操作——通常是 1000 倍或更多。与电话簿相比,索引可以让你直接查找一个人,因为它已经按字母顺序排序了。如果电话簿只是一百万个名字及其电话号码的无序列表,那么您需要花费一个月的时间才能找到一个电话号码。
插入
作为保持索引有序的自然结果,它会增加您对数据执行的任何更改的开销。继续电话簿类比,如果添加姓名,则必须按正确的字母顺序插入姓名,这比仅将记录添加到表末尾要花费更多的时间/工作。
更新中
索引将大大提高您查找数据的速度,但如果您更改索引列中的值,数据将不得不在表中物理移动以保持正确的顺序。
删除
同样,与在整个表中查找正确的记录相比,索引将帮助您非常快速地找到记录。通常,删除不会重新组织索引——它只会在行所在的位置留下一个空洞,尽管这在数据库服务器之间可能有所不同。
总之
更改索引表中的数据将花费更长的时间,而通过适当的索引选择数据会快得多。就像@ypercube 所说的那样,过度索引不仅会减慢更改操作的速度,还会迫使服务器选择正确的索引,如果要经过上千个选择,这将花费很长时间。
在某些边缘情况下,您可能不想为表编制索引:例如,当您需要插入大量记录时,并且在读取这些记录后您没有兴趣对这些记录进行过滤或排序。例如,我会考虑将此用于(非增量)用于 OLAP 多维数据集的事实表 - 它被填充一次,并在没有任何特定排序顺序的情况下完整读取一次。
已经有很多好的答案了。我只想添加一条经验法则和最坏的情况。
经验法则:如果一个索引不被 SEEK 操作频繁使用,它可以被认为是“坏的”,应该被修改或删除。
最坏的情况:sql server 中的聚集索引由 GUID(非顺序)列组成,因此频繁插入可能会导致物理数据重新分配。