【发布时间】:2023-03-15 17:25:01
【问题描述】:
创建集合类型:
CREATE TYPE nums_list AS TABLE OF NUMBER;
用集合类型的列创建表(嵌套表列):
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;
然后运行查询以查找集合类型中的元素:
select count(*) from test1 where 8 member of tagged;
此查询运行缓慢,执行时间约为 7-8 秒。
问题:如何加快执行时间?可能是索引?但是我不明白如何为嵌套表列使用索引。
附:我尝试使用循环检查 PL/SQL 块中的每一行,使用游标,然后将结果作为流水线表函数返回,但这比直接查询要慢。
【问题讨论】:
-
在您编写示例时,我认为从 600,000 开始的所有行都将在列表中具有数字 8。这意味着,您的查询将返回 400,000(在 1,000,000 行中)。嵌套表与否,这不是索引将有很大帮助的查询类型。这是您在示例中的意图,让这么多行满足查询吗?
-
@Matthew -- 是的,正好 400,001 行返回此查询。数据这么大吗?
-
它本身并不是“大”。就是它占表中总行数的很大比例。在这种情况下,读取整个表(即“全表扫描”)来执行搜索比 400,000 次索引查找更有效。全扫描可以在单个 I/O 中读取许多表块,而索引查找将需要 3-4 个 I/O每行。对于这样一个狭窄的表,全表扫描可能需要不到 100,000 次 I/O(粗略猜测),而带有索引的嵌套循环连接可能需要超过 100 万次 I/O。
-
有什么理由需要存储一个集合吗?一般来说,将其存储为子表会更加传统,这样子表就会有很多很多的性能调整选项。
-
@JustinCave -- 唯一的原因是我有行(项目),它可能被 10 个不同的标签标记,所以如果将这些存储在子表中,每个项目将有 10 行(10此项目的每个标签的行)。在集合的情况下,单个项目只有一行,但你是对的,另一张表似乎更好。此外,从 Matthew 的回答来看,无论如何都发生了“取消嵌套”集合