我有一个巨大的表(一种审计日志),其中包含以下列:
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索引呢?如果是的话,怎么办?
如果您绝对无法在表上创建索引,那么您可以执行以下操作:
您可以将这些步骤合并到一个查询中:
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