我有一个表,它基本上是一个带有parent_id
列和id
列的树结构。
parent_id
为null
。
还有一个自引用外键,因此每个parent_id
都有一个对应的id
。
此表主要是只读的,主要是不经常批量更新。
访问此表的应用程序中最常见的查询之一是select ... where parent_id = X
。我认为如果这个表是parent_id
上的索引组织,这可能会更快。
但是,如果parent_id
可以是null
,我不确定如何对此表进行索引编制。我宁愿不捏造东西,以便parent_id=0
是一些特殊的id,因为我必须向表中添加虚拟值以确保满足外键约束,并且它还会更改应用程序逻辑。
有没有办法按可能的null
值列索引组织表?
答案 0 :(得分:1)
提问者的解决方案:
我发现只要将查询的列添加到parent_id
索引的末尾,我就可以从索引组织中获得相同的好处,即代替:
create index foo_idx on foo_tab(parent_id);
我做:
create index foo_idx on foo_tab(parent_id, col1, col2, col3);
col1
,col2
,col3
等频繁访问的列。
我只使用索引来完成此操作,这些索引用于返回多个行,这些行从索引提供的排序和磁盘位置中受益,而不必跳转到表。索引通常用于返回我留给引用表的单行,因为无论如何只需要读取一行,因此局部性更不重要。
就像我提到的,这是一个主要的读表,并且空间也不是一个大问题,所以我不认为这些索引引起的写入开销是一个很大的问题。
(我意识到这不会索引null
parent_id
s,而是我在decode(parent_id, null, 1, null)
上创建了另一个索引,该索引对空值进行索引并且仅为空值。
答案 1 :(得分:0)
我会尝试在单列parent_id上添加索引。
如果索引中的所有列都为非null,则此行不会出现在索引中。
因此,对于上面引用的parent_id = X
,这应该使用索引。但是,如果您正在执行parent_id is null
,那么它将不会使用索引,您将获得与现在相同的性能。这听起来像是适合你的行为。
我过去曾使用它来改善查询的性能。如果索引中的项目数与数据库中的行数相比较小,则可以很好地工作。在这个特定的索引中,我们有大约3%的行,它飞了: - )
但是,与往常一样,您需要尝试并测量性能差异。您的里程可能会有所不同。