Oracle 集合类型列中的快速搜索

Oracle 集合类型列中的快速搜索,oracle,plsql,oracle12c,Oracle,Plsql,Oracle12c,创建集合类型: CREATE TYPE nums_list AS TABLE OF NUMBER; select count(*) from test1 where 8 member of tagged; 使用集合类型为嵌套表列的列创建表: CREATE TABLE test1 ( num NUMBER, tagged nums_list ) NESTED TABLE tagged STORE AS mytest_tagged_table; 在表中插

创建集合类型:

CREATE TYPE nums_list AS TABLE OF NUMBER;
    select count(*) from test1 where 8 member of tagged;
使用集合类型为嵌套表列的列创建表:

CREATE TABLE test1 (
        num NUMBER,
        tagged nums_list
)
NESTED TABLE tagged STORE AS mytest_tagged_table;
在表中插入100万行:

DECLARE 
    tagg_value nums_list := nums_list(3,4,5);
BEGIN
    for i in 1..1000000 loop
          if i = 600000 then
              tagg_value := nums_list(7,8);
          end if;

          INSERT INTO test1
          (num, tagged)
          VALUES
          (i, tagg_value);
    end loop;
END;
然后运行查询以搜索集合类型中的元素:

CREATE TYPE nums_list AS TABLE OF NUMBER;
    select count(*) from test1 where 8 member of tagged;
此查询运行缓慢,执行时间约为7-8秒

问题:如何加快执行时间?可能是索引吗?但我不知道如何为嵌套表列使用索引

另外,我尝试使用循环检查PL/SQL块中的每一行,使用游标,然后将结果作为流水线表函数返回,但这比直接查询慢。

如果您在示例中对此查询执行解释计划:

select count(*) from test1 where 8 member of tagged;
。。。您将看到Oracle可能正在mytest_tagged_表上使用系统生成的索引来提高性能。它仍然需要这么长时间的原因是400000个索引查找实际上比仅仅读取整个表的效率要低

所以,问题不是如何让Oracle在嵌套表中使用索引?我怎么能让甲骨文不这么做

由于标记列表看起来很小,您有一种选择,就是使用VARRAY。虽然相关的语法没有那么干净,但是这些可以内联存储以获得更好的性能

以下是为VARRAY修改的示例:

在我的系统上,这只需要3600个缓冲区就可以运行,而您的示例查询需要210万个缓冲区。相应地,它也运行得更快


varray不是嵌套表的直接等价物,它们附带了警告。但是,根据您的示例,它们可能就是您要查找的内容。

在您编写示例时,我认为从600000开始的所有行都将在列表中包含数字8。这意味着您的查询将返回1000000行中的400000行。不管是否是嵌套表,索引对查询类型都没有多大帮助。在本例中,您的意图是让这么多行满足查询吗?@Matthew-Yes确切地说400001行返回此查询。这是如此大的数据吗?它本身并不是那么大。值得注意的是,它占表中总行数的很大百分比。在这种情况下,读取整个表(即执行搜索的全表扫描)比400000索引查找更有效。完整扫描可以在一个I/O中读取多个表块,而索引查找每行需要3-4个I/O。对于这样窄的表,完整表扫描可能需要不到100000个I/O的粗略猜测,而带有索引的嵌套循环联接可能需要超过一百万个I/O。您需要存储集合的原因是什么?一般来说,将其存储为子表将更为传统,然后子表将有许多、更多的性能调整选项-唯一的原因是我有行项,它可能由10个不同的标记进行标记,因此如果将这些存储在子表中,则每个项将有10行,每个项的每个标记有10行。在集合的情况下,单个项目只有一行,但您是对的,另一个表似乎更好。另外,从马修的回答来看,无论如何,收藏品的不耐烦也发生了