1

我有一个带有三个表的 OLTP 应用程序

Item Table - ItemId, CategoryId, AgeGroupId, ... 100K rows. 

CategoryTable - CategoryId, ...  (only 5-10 rows)
AgeGroupTable - AgeGroupId, ...  (only 4-5 rows) 

Item 表CategoryId的合适索引是什么?AgeGroupId最好通过它们或两者来查询Category项目Agegroup

我在想位图索引可能由于基数低而起作用,但我不知道它们如何与每个表的多个位图索引一起工作?如果有的话,水平分区有什么帮助?

4

3 回答 3

2

这开始是一个评论,但它变得太长了。

CategoryId 和 AgeGroupId 的合适索引是什么?

在什么情况下?在您的示例架构中,这两个数据域都显示为主键和外键。然而,这无关紧要。

您应该只在它们实际要增加价值的地方添加索引,并且每个表中的行少于 10 行,除非数据非常倾斜,否则对任何一个域进行索引都没有任何好处。插入/更新将更慢,通过这样的索引访问数据将比对 3 个表中的每一个执行全表扫描要慢。

项目表中的其他属性之间可能存在隐式关系,因此将域添加到其他索引(但不是在前面)是有意义的,但在不了解更多关于数据和针对它运行的查询的情况下,我会忽略现在这个。

于 2012-12-09T23:53:40.487 回答
2

由于这是一个 OLTP 应用程序,您几乎肯定不想使用位图索引。位图索引往往不适用于 OLTP 应用程序。当您对数据执行大量单行操作时,它们的大小往往会迅速增长(尽管在最近的版本中这种影响有所减轻)。但更重要的是,锁定影响往往会从根本上降低应用程序的可伸缩性。例如,如果您在 上具有位图索引,则CategoryID更新单行CategoryID将实际上需要锁定表中具有CategoryID源值或目标值的每一行。

听起来,您最多需要 ( AgeGroupID, CategoryID) 和 ( CategoryID, AgeGroupID) 上的复合索引。潜在地,您可以仅在 ( AgeGroupID, CategoryID) 上使用复合索引,并让 Oracle 使用索引跳过扫描(如果仅CategoryID指定)。这取决于您想要做出的权衡——多个索引将使查询CategoryID更有效,但代价是对 DML 操作的额外索引维护和额外的磁盘空间使用。

您是否获得使用分区的许可?这是企业版许可证之上的额外费用选项。我想,您可能可以对表进行分区。不过,只有 100,000 行的表非常小,无法考虑分区。无论您使用什么分区,都会使不使用分区键的查询效率降低。如果您知道指定AgeGroupID的查询比CategoryID(反之亦然)更常见,但这听起来不像您所描述的那样,这可能是有道理的。

于 2012-12-10T03:08:39.467 回答
0

这实际上取决于您的查询是什么样的。如果您总是一次只过滤或加入一列,那么位图索引将正常工作。如果您将基于两列进行过滤或连接,则复合索引也可以工作。

以我的经验,最好的确定方法是测试这两个选项。我已经成功地将多个位图索引放在一个表上,以及使用复合索引。表中只有 100K 行,您应该能够非常快速地创建和删除索引。然后,您可以使用不同的索引集测试最常见的查询。

于 2012-12-10T02:17:11.370 回答