暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 对最新记录的乐观搜索

askTom 2017-11-08
246

问题描述

嗨,

我有非常大的表,表不断增长。搜索由ID列执行,该列是PK的一部分。
create table TEST (
 ID         varchar2(20) primary key,
 VALUE      varchar2(20),
 CREATED_TS timestamp default := systimestamp
);

同时,大多数select查询都在寻找相对较新的记录 (即几个月)。为了避免一直进行全索引扫描,我可以尝试分两步执行查询-首先,我使用其他谓词搜索时间范围,即

select * from TEST where ID='xyz' and CREATED_TS > systimestamp-100


只有当找不到记录时,我才会对所有日期执行查询-

select * from TEST where ID='xyz'


将被限制为只有一个查询的时间99%。很好,特别是如果我们在 (CREATED_TS,ID) 上添加索引。但是当我需要搜索ID值列表时,即使用
"ID in ('val1', 'val2', 'val3'...)"
语法。在这种情况下,我需要通过第一步找不到的值来缩小第二步的列表。这很不方便。

是否可以使用内置的Oracle功能来实现相同的逻辑?例如,我正在考虑通过CREATED_TS范围对表进行分区。如果可以以某种方式让Oracle知道它应该在最近的分区中开始搜索,则可以解决挑战。但是我不知道有序分区扫描的优化提示。

我不认为这是不寻常的情况,所以期待一些已经存在的解决方案从Oracle。

谢谢,
亚历山大

专家解答

关于

"select * from TEST where ID='xyz' and CREATED_TS > systimestamp-100
an only if record is not found I will execute query for all dates -
select * from TEST where ID='xyz'
"


如果您在ID上有索引,CREATED_TS,那么您将不需要第一个查询-是否有ID的数据。然后可以将相同的逻辑应用于多个ID。优化器应该迭代地处理它们以利用该索引,或者最坏的情况是,您可以将它们表述为UNION ALL。

但是,如果您的测试用例是对更一般情况的简化,即,用户给出了完全临时的搜索条件,并且您想 * 首先 * 搜索最近的数据,那么在这种情况下,在适当的日期/时间戳列上进行分区是一种有效的策略,因为仅对相关分区进行全面扫描就可以提高查询性能。分区也有助于满足以下要求: “首先检查最近,否则返回更远”,因为您可以将查询表述为:
查询1: 其中 [标准] 和ts >= [起点]
查询2: 其中 [标准] 和ts <[起点]

这避免了重复扫描最近的分区。

无论哪种情况,都可以使用良好的应用程序工具来识别随时间推移的 “流行” 查询,并且可以使用专门的索引来处理最常见的查询,以提供良好的用户体验。

显然,这里还有其他因素可能会发挥作用。例如,如果您有一个Exadata系统,那么存储索引可能会减轻分区等的需求。

希望这有所帮助。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论