oracle - 行上两个不相关的类别 - 如何索引?

时间:2012-12-09 23:22:38

标签: sql oracle

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

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

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

Item表的CategoryIdAgeGroupId的适当索引是什么?最好通过CategoryAgegroup或两者来查询项目!

我认为由于基数较低,位图索引可能会起作用,但我不知道它们对每个表的多个位图索引有多精确?如果有的话,水平分区将如何帮助?

3 个答案:

答案 0 :(得分:2)

这开头是一个评论,但它太长了。

  

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

在什么情况下?这两个数据域在示例模式中显示为主键和外键。然而,这不是重点。

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

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

答案 1 :(得分:2)

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

听起来,您最多需要(AgeGroupIDCategoryID)和(CategoryIDAgeGroupID)上的复合索引。可能只能在(AgeGroupIDCategoryID)上使用复合索引,如果仅指定CategoryID,则让Oracle使用索引跳过扫描。这取决于您想要进行的权衡 - 多个索引将使CategoryID上的查询更加高效,代价是对DML操作的额外索引维护和额外的磁盘空间使用。

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

答案 2 :(得分:0)

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

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