我正在开发一个带有相当大的Oracle数据库的项目(尽管我的问题同样适用于其他数据库).我们有一个Web界面,允许用户搜索几乎任何可能的字段组合.
为了使这些搜索更快,我们将索引添加到我们认为用户通常会搜索的字段和字段组合.但是,由于我们并不真正了解客户将如何使用此软件,因此很难确定要创建哪些索引.
空间不是一个问题; 我们有一个4 TB的RAID驱动器,我们只使用了一小部分.但是,我担心索引太多会导致性能损失.因为每次添加,删除或修改行时都需要更新这些索引,我想在单个表上有几十个索引是个坏主意.
那么有多少指数被认为太多了?10?25?50?或者我应该只是覆盖真正的,非常常见和明显的案例而忽略其他一切?
这取决于表上发生的操作.
如果有很多SELECT和很少的更改,索引你喜欢的所有....这些(可能)加速SELECT语句.
如果表受到UPDATE,INSERTs + DELETE的严重影响......由于每次执行其中一个操作时都需要修改这些索引,因此这些索引会非常慢
话虽如此,你可以清楚地向一个不会做任何事情的表中添加许多无意义的索引.将B-Tree索引添加到具有2个不同值的列将是没有意义的,因为它不会在查找数据方面添加任何内容.列中的值越独特,它就越能从索引中受益.
我通常这样做.
获取真实的日志在典型日期对数据运行查询.
添加索引,以便最重要的查询在其执行计划中命中索引.
尽量避免索引具有大量更新或插入的字段
在几个索引之后,获取一个新日志并重复.
与所有任何优化一样,我在达到要求的性能时停止(这显然意味着第0点将获得特定的性能要求).
其他人一直在给你很好的建议.当你前进时,我有一个额外的建议.在某些时候,您必须决定您的最佳索引策略.最后,最好的PLANNED索引策略仍然可以最终创建最终不会被使用的索引.允许您查找未使用的索引的一种策略是监视索引使用情况.你这样做如下: -
alter index my_index_name monitoring usage;
然后,您可以通过查询v $ object_usage来监视从该点开始是否使用索引.有关此内容的信息,请参见Oracle®数据库管理员指南.
请记住,如果您在更新表之前有一个删除索引的仓储策略,然后重新创建它们,则必须再次设置索引以进行监视,并且您将丢失该索引的任何监视历史记录.
在数据仓库中,拥有大量索引是很常见的.我使用的事实表有两百列,其中190列已编入索引.
虽然有一个开销,但必须在上下文中理解,在数据仓库中我们通常只插入一次行,我们从不更新它,但它可以参与成千上万的SELECT查询,这些查询可能会受益于任何一个上的索引.列.
为了获得最大的灵活性,数据仓库通常使用单列位图索引,但在高基数列上除外,其中可以使用(压缩的)btree索引.
索引维护的开销主要与写入大量块的开销以及块拆分相关联,因为添加了新行,其值为该列的现有值范围的"中间".这可以通过分区并使新数据加载与分区方案对齐并通过使用直接路径插入来减轻.
为了更直接地解决你的问题,我认为最初可以对明显的索引进行索引,但是如果针对表的查询会受益,不要害怕添加更多的索引.
在爱因斯坦的解释中关于简单性,根据需要添加尽可能多的索引,而不是更多.
但是,严重的是,只要将数据添加到表中,您添加的每个索引都需要维护.在主要是只读的表上,很多索引都是好事.在高度动态的表格上,越少越好.
我的建议是涵盖常见和明显的案例,然后,当您遇到需要更快速地从特定表中获取数据的问题时,请在此时评估和添加索引.
此外,每隔几个月重新评估一次索引方案是一个好主意,只是为了看看是否有任何新的需要索引或者你创建的任何索引都没有被用于任何东西,应该被删除.
除了其他人提出的要点之外,如果有更多的索引,那么在为SQL语句创建计划时,基于成本的优化程序会产生成本,因为有更多的组合需要考虑.您可以通过正确使用绑定变量来减少这种情况,以便SQL语句保留在SQL缓存中.然后,Oracle可以进行软解析并重新使用上次找到的计划.
一如既往,没有什么是简单的.如果涉及倾斜的列和直方图,那么这可能是一个坏主意.
在我们的Web应用程序中,我们倾向于限制我们允许的搜索组合.否则你将不得不测试每个组合的性能,以确保你没有潜伏的问题,有人会找到一天.我们还实现了资源限制来阻止这会导致应用程序中的其他地方出现问题.
我对我的真实项目和真正的MySql数据库进行了一些简单的测试.我已在本主题中回答:索引多个数据库列的成本是多少?
但我认为如果我在这里引用它会更好:
我使用我的真实项目和真正的MySql数据库进行了一些简单的测试.
我的结果是:将平均索引(索引中的1-3列)添加到表中 - 使插入速度降低2.1%.因此,如果添加20个索引,则插入速度将降低40-50%.但你的选择将快10到100倍.
那么可以添加很多索引吗? - 这取决于:)我给你我的结果 - 你决定!