当搜索列未建立索引但与索引具有相同顺序时如何使用索引

问题描述 投票:0回答:1

我有一个巨大的表(一种审计日志),其中包含以下列:

ID, TS, DATA
  • ID
    是主键,它是序列中的数字。
  • TS
    是一个时间戳,它是插入的当前时间戳。
  • DATA
    是有用的数据。

可以保证,如果记录“B”的 ID 大于记录“A”,则“B”的时间戳将大于或等于“A”的时间戳。

我的目标是选择给定时间间隔的记录。与表格涵盖的总时间(天与年)相比,时间间隔始终非常短。

如果我简单问一下

select * 
from audit 
where TS > 20220101 and TS < 20220102

然后进行全表扫描,这会花费太多时间。

如果我先找出每天的第一个ID,并知道20220101的第一个ID是123456,20220102的第一个ID是145678,那么我可以问

select * 
from audit 
where ID > 123456 and ID < 145678

速度很快,因为会进行索引扫描。

所以很明显,我应该以某种方式找出给定时间段的第一个和最后一个 ID 并使用它们,而不是全表扫描。很明显,由于 ID 和 TS 之间的相关性,我可以通过二分搜索快速找到 ID。但我不知道如何在 SQL 查询中执行此操作(如果可能的话)。

我想 TS 上的索引可以解决这个问题,但不幸的是我无法向表添加索引。

那么这个查询是否可以使用ID索引呢?如果是的话,怎么办?

sql oracle indexing relational-database binary-search
1个回答
0
投票

如果您绝对无法在表上创建索引,那么您可以执行以下操作:

  1. 找到上限ID。
  2. 找到下限 ID。
  3. 使用上限和下限 ID 来查找条目。

您可以将这些步骤合并到一个查询中:

with boundries as (
  select (
    select ID
    from audit
    where TS < 20220102
    order by ID desc
    limit 1
  ) as upper,
  (
    select ID
    from audit
    where TS > 20220101
    order by ID
    limit 1
  ) as lower
)
select *
from audit
where ID <= (select upper from boundries)
and ID >= (select lower from boundries)
order by ID
© www.soinside.com 2019 - 2024. All rights reserved.